storybook-addon-pseudo-states 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/manager.mjs +2 -2
- package/dist/manager.mjs.map +1 -1
- package/dist/preview.js +3 -3
- package/dist/preview.js.map +1 -1
- package/dist/preview.mjs +2 -2
- package/dist/preview.mjs.map +1 -1
- package/package.json +1 -1
package/dist/manager.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { addons, types, useGlobals } from '@storybook/manager-api';
|
|
2
2
|
import e, { useCallback } from 'react';
|
|
3
3
|
import { WithTooltip, TooltipLinkList, IconButton } from '@storybook/components';
|
|
4
|
-
import { CheckIcon } from '@storybook/icons';
|
|
4
|
+
import { CheckIcon, ButtonIcon } from '@storybook/icons';
|
|
5
5
|
import { styled, color } from '@storybook/theming';
|
|
6
6
|
|
|
7
|
-
var r="storybook/pseudo-states",
|
|
7
|
+
var r="storybook/pseudo-states",n=`${r}/tool`,c="pseudo";var l={hover:"hover",active:"active",focusVisible:"focus-visible",focusWithin:"focus-within",focus:"focus",visited:"visited",link:"link",target:"target"};var b=styled.span(({active:o})=>({color:o?color.secondary:"inherit"})),_=styled(CheckIcon)(({active:o})=>({opacity:o?1:0,path:{fill:o?color.secondary:"inherit"}})),a=Object.keys(l).sort(),f=()=>{let[o,m]=useGlobals(),s=o[c],i=useCallback(t=>s?s[t]===!0:!1,[s]),d=useCallback(t=>()=>{m({[c]:{...s,[t]:!i(t)}});},[s]);return e.createElement(WithTooltip,{placement:"top",trigger:"click",tooltip:()=>e.createElement(TooltipLinkList,{links:a.map(t=>({id:t,title:e.createElement(b,{active:i(t)},":",l[t]),right:e.createElement(_,{width:12,height:12,active:i(t)}),onClick:d(t),active:i(t)}))})},e.createElement(IconButton,{key:"pseudo-state",title:"Select CSS pseudo states",active:a.some(i)},e.createElement(ButtonIcon,null)))};addons.register(r,()=>{addons.add(n,{type:types.TOOL,title:"CSS pseudo states",match:({viewMode:o})=>o==="story",render:f});});
|
|
8
8
|
//# sourceMappingURL=out.js.map
|
|
9
9
|
//# sourceMappingURL=manager.mjs.map
|
package/dist/manager.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/manager.ts","../src/constants.ts","../src/manager/PseudoStateTool.tsx"],"names":["addons","types","ADDON_ID","TOOL_ID","PARAM_KEY","PSEUDO_STATES","React","useCallback","IconButton","WithTooltip","TooltipLinkList","CheckIcon","useGlobals","styled","color","LinkTitle","active","LinkIcon","options","PseudoStateTool","globals","updateGlobals","pseudo","isActive","option","toggleOption","viewMode"],"mappings":"AAAA,OAAS,UAAAA,EAAQ,SAAAC,MAAa,yBCAvB,IAAMC,EAAW,0BACXC,EAAU,GAAGD,CAAQ,QACrBE,EAAY,SAQlB,IAAMC,EAAgB,CAC3B,MAAO,QACP,OAAQ,SACR,aAAc,gBACd,YAAa,eACb,MAAO,QACP,QAAS,UACT,KAAM,OACN,OAAQ,QACV,ECnBA,OAAOC,GAAS,eAAAC,MAAmB,QACnC,OAAS,cAAAC,EAAY,eAAAC,EAAa,mBAAAC,MAAuB,wBACzD,OAAS,aAAAC,
|
|
1
|
+
{"version":3,"sources":["../src/manager.ts","../src/constants.ts","../src/manager/PseudoStateTool.tsx"],"names":["addons","types","ADDON_ID","TOOL_ID","PARAM_KEY","PSEUDO_STATES","React","useCallback","IconButton","WithTooltip","TooltipLinkList","CheckIcon","ButtonIcon","useGlobals","styled","color","LinkTitle","active","LinkIcon","options","PseudoStateTool","globals","updateGlobals","pseudo","isActive","option","toggleOption","viewMode"],"mappings":"AAAA,OAAS,UAAAA,EAAQ,SAAAC,MAAa,yBCAvB,IAAMC,EAAW,0BACXC,EAAU,GAAGD,CAAQ,QACrBE,EAAY,SAQlB,IAAMC,EAAgB,CAC3B,MAAO,QACP,OAAQ,SACR,aAAc,gBACd,YAAa,eACb,MAAO,QACP,QAAS,UACT,KAAM,OACN,OAAQ,QACV,ECnBA,OAAOC,GAAS,eAAAC,MAAmB,QACnC,OAAS,cAAAC,EAAY,eAAAC,EAAa,mBAAAC,MAAuB,wBACzD,OAAS,aAAAC,EAAW,cAAAC,MAAkB,mBACtC,OAAS,cAAAC,MAAkB,yBAC3B,OAAS,UAAAC,EAAQ,SAAAC,MAAa,qBAI9B,IAAMC,EAAYF,EAAO,KAA2B,CAAC,CAAE,OAAAG,CAAO,KAAO,CACnE,MAAOA,EAASF,EAAM,UAAY,SACpC,EAAE,EAEIG,EAAWJ,EAAOH,CAAS,EAAwB,CAAC,CAAE,OAAAM,CAAO,KAAO,CACxE,QAASA,EAAS,EAAI,EACtB,KAAM,CAAE,KAAMA,EAASF,EAAM,UAAY,SAAU,CACrD,EAAE,EAEII,EAAU,OAAO,KAAKd,CAAa,EAAE,KAAK,EAEnCe,EAAkB,IAAM,CACnC,GAAM,CAACC,EAASC,CAAa,EAAIT,EAAW,EACtCU,EAASF,EAAQjB,CAAS,EAE1BoB,EAAWjB,EACdkB,GACMF,EACEA,EAAOE,CAAM,IAAM,GADN,GAGtB,CAACF,CAAM,CACT,EAEMG,EAAenB,EAClBkB,GAAuC,IAAM,CAC5CH,EAAc,CACZ,CAAClB,CAAS,EAAG,CACX,GAAGmB,EACH,CAACE,CAAM,EAAG,CAACD,EAASC,CAAM,CAC5B,CACF,CAAC,CACH,EACA,CAACF,CAAM,CACT,EAEA,OACEjB,EAAA,cAACG,EAAA,CACC,UAAU,MACV,QAAQ,QACR,QAAS,IACPH,EAAA,cAACI,EAAA,CACC,MAAOS,EAAQ,IAAKM,IAAY,CAC9B,GAAIA,EACJ,MAAOnB,EAAA,cAACU,EAAA,CAAU,OAAQQ,EAASC,CAAM,GAAG,IAAEpB,EAAcoB,CAAM,CAAE,EACpE,MAAOnB,EAAA,cAACY,EAAA,CAAS,MAAO,GAAI,OAAQ,GAAI,OAAQM,EAASC,CAAM,EAAG,EAClE,QAASC,EAAaD,CAAM,EAC5B,OAAQD,EAASC,CAAM,CACzB,EAAE,EACJ,GAGFnB,EAAA,cAACE,EAAA,CACC,IAAI,eACJ,MAAM,2BACN,OAAQW,EAAQ,KAAKK,CAAQ,GAE7BlB,EAAA,cAACM,EAAA,IAAW,CACd,CACF,CAEJ,EF/DAZ,EAAO,SAASE,EAAU,IAAM,CAC9BF,EAAO,IAAIG,EAAS,CAClB,KAAMF,EAAM,KACZ,MAAO,oBACP,MAAO,CAAC,CAAE,SAAA0B,CAAS,IAAMA,IAAa,QACtC,OAAQP,CACV,CAAC,CACH,CAAC","sourcesContent":["import { addons, types } from \"@storybook/manager-api\"\n\nimport { ADDON_ID, TOOL_ID } from \"./constants\"\nimport { PseudoStateTool } from \"./manager/PseudoStateTool\"\n\naddons.register(ADDON_ID, () => {\n addons.add(TOOL_ID, {\n type: types.TOOL,\n title: \"CSS pseudo states\",\n match: ({ viewMode }) => viewMode === \"story\",\n render: PseudoStateTool,\n })\n})\n","export const ADDON_ID = \"storybook/pseudo-states\"\nexport const TOOL_ID = `${ADDON_ID}/tool`\nexport const PARAM_KEY = \"pseudo\"\n\n// Regex patterns for pseudo-elements which are not allowed to have classes applied on them\n// E.g. ::-webkit-scrollbar-thumb.pseudo-hover is not a valid selector\nexport const EXCLUDED_PSEUDO_ELEMENT_PATTERNS = [\"::-webkit-scrollbar-thumb\", \"::-webkit-slider-thumb\", \"::part\\\\([^)]+\\\\)\"]\n\n// Dynamic pseudo-classes\n// @see https://www.w3.org/TR/2018/REC-selectors-3-20181106/#dynamic-pseudos\nexport const PSEUDO_STATES = {\n hover: \"hover\",\n active: \"active\",\n focusVisible: \"focus-visible\",\n focusWithin: \"focus-within\",\n focus: \"focus\", // must come after its alternatives\n visited: \"visited\",\n link: \"link\",\n target: \"target\",\n} as const\n\nexport type PseudoState = keyof typeof PSEUDO_STATES\n","import React, { useCallback } from \"react\"\nimport { IconButton, WithTooltip, TooltipLinkList } from \"@storybook/components\"\nimport { CheckIcon, ButtonIcon } from \"@storybook/icons\"\nimport { useGlobals } from \"@storybook/manager-api\"\nimport { styled, color } from \"@storybook/theming\"\n\nimport { PARAM_KEY, PSEUDO_STATES } from \"../constants\"\n\nconst LinkTitle = styled.span<{ active?: boolean }>(({ active }) => ({\n color: active ? color.secondary : \"inherit\",\n}))\n\nconst LinkIcon = styled(CheckIcon)<{ active?: boolean }>(({ active }) => ({\n opacity: active ? 1 : 0,\n path: { fill: active ? color.secondary : \"inherit\" },\n}))\n\nconst options = Object.keys(PSEUDO_STATES).sort() as (keyof typeof PSEUDO_STATES)[]\n\nexport const PseudoStateTool = () => {\n const [globals, updateGlobals] = useGlobals()\n const pseudo = globals[PARAM_KEY]\n\n const isActive = useCallback(\n (option: keyof typeof PSEUDO_STATES) => {\n if (!pseudo) return false\n return pseudo[option] === true\n },\n [pseudo],\n )\n\n const toggleOption = useCallback(\n (option: keyof typeof PSEUDO_STATES) => () => {\n updateGlobals({\n [PARAM_KEY]: {\n ...pseudo,\n [option]: !isActive(option),\n },\n })\n },\n [pseudo],\n )\n\n return (\n <WithTooltip\n placement=\"top\"\n trigger=\"click\"\n tooltip={() => (\n <TooltipLinkList\n links={options.map((option) => ({\n id: option,\n title: <LinkTitle active={isActive(option)}>:{PSEUDO_STATES[option]}</LinkTitle>,\n right: <LinkIcon width={12} height={12} active={isActive(option)} />,\n onClick: toggleOption(option),\n active: isActive(option),\n }))}\n />\n )}\n >\n <IconButton\n key=\"pseudo-state\"\n title=\"Select CSS pseudo states\"\n active={options.some(isActive)}\n >\n <ButtonIcon />\n </IconButton>\n </WithTooltip>\n )\n}\n"]}
|
package/dist/preview.js
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
var coreEvents = require('@storybook/core-events');
|
|
4
4
|
var previewApi = require('@storybook/preview-api');
|
|
5
5
|
|
|
6
|
-
var g="pseudo",R=["::-webkit-scrollbar-thumb","::-webkit-slider-thumb"],u={hover:"hover",active:"active",focusVisible:"focus-visible",focusWithin:"focus-within",focus:"focus",visited:"visited",link:"link",target:"target"};var k=e=>e.indexOf("@")===0,y=e=>{if(k(e))return [e];let o=[],t=0,s=0,
|
|
6
|
+
var g="pseudo",R=["::-webkit-scrollbar-thumb","::-webkit-slider-thumb","::part\\([^)]+\\)"],u={hover:"hover",active:"active",focusVisible:"focus-visible",focusWithin:"focus-within",focus:"focus",visited:"visited",link:"link",target:"target"};var k=e=>e.indexOf("@")===0,y=e=>{if(k(e))return [e];let o=[],t=0,s=0,n="";for(let r=0,c=e.length;r<c;r++){let a=e[r];if(a==="(")t+=1;else if(a===")")t-=1;else if(a==="[")s+=1;else if(a==="]")s-=1;else if(a===","&&!t&&!s){o.push(n.trim()),n="";continue}n+=a;}return o.push(n.trim()),o};var b=Object.values(u),A=`:(${b.join("|")})`,h=new RegExp(A),j=new RegExp(A,"g"),P=new Set,w=e=>{P.has(e)||(console.warn(e),P.add(e));},d=(e,o)=>{let t=`(?<!(?:${R.join("|")})\\S*)`;return b.reduce((s,n)=>s.replace(new RegExp(`${t}:${n}`,"g"),`.pseudo-${n}${o?"-all":""}`),e)},m=(e,o,t)=>{let{states:s,withoutPseudoStates:n}=U(e);if(s.length===0&&!t)return e;let r=`${t??""}${s.map(c=>`.pseudo-${c}-all`).join("")}`;return n=n.replace(":host-context(*)","").trimStart(),n.startsWith(":host-context(")?n.replace(new RegExp("(?<=:host-context\\(\\S+)\\)"),`)${r}`):o?`:host(${r}) ${n}`:`${r} ${n}`},U=e=>{let o=new Set,t=e.replace(j,(s,n)=>(o.add(n),"")).replaceAll("()","(*)").replace(new RegExp("(?<=[\\s(]),\\s+|(,\\s+)+(?=\\))","g"),"")||"*";return {states:Array.from(o),withoutPseudoStates:t}},_=(e,o)=>[...e.matchAll(/:not\(([^)]+)\)/g)].reduce((t,s)=>{let n=s[0],r=s[1],c=q(r,o);return t.replace(n,c)},e),q=(e,o)=>{let t=[];for(let s of e.split(/,\s*/))t.push(m(s,o));return `:not(${t.join(", ")})`},v=({cssText:e,selectorText:o},t)=>e.replace(o,y(o).flatMap(s=>{if(s.includes(".pseudo-"))return [];let n=[s];if(!h.test(s))return n;let r=d(s);r!==s&&n.push(r);let c="";if(s.startsWith(":host(")){let a=s.match(/^:host\((\S+)\)\s+(.+)$/);if(a&&h.test(a[2])){let l=a[1],i=a[2];l=d(l,!0),i=_(i,!0),c=m(i,!0,l);}else c=d(s,!0);}else {let a=_(s,t);c=m(a,t);}return n.push(c),n}).join(", ")),O=(e,o=!1)=>{try{let s=x(e,1e3,o);return s>=1e3&&w("Reached maximum of 1000 pseudo selectors per sheet, skipping the rest."),s>0}catch(t){return String(t).includes("cssRules")?w(`Can't access cssRules, likely due to CORS restrictions: ${e.href}`):console.error(t,e.href),!1}},x=(e,o,t)=>{let s=0,n=-1;for(let r of e.cssRules){n++;let c=0;if(r.__processed)c=r.__pseudoStatesRewrittenCount;else {if("cssRules"in r&&r.cssRules.length)c=x(r,o-s,t);else {if(!("selectorText"in r))continue;let a=r;if(h.test(a.selectorText)){let l=v(a,t);e.deleteRule(n),e.insertRule(l,n),c=1;}}r.__processed=!0,r.__pseudoStatesRewrittenCount=c;}if(s+=c,s>=o)break}return s};var S=previewApi.addons.getChannel(),f=new Set,C=(e,o)=>{Object.values(u).forEach(t=>{e.classList.remove(`pseudo-${t}`),e.classList.remove(`pseudo-${t}-all`);}),o.forEach(t=>e.classList.add(t));};function E(e,o){let t=[];return e.querySelectorAll("*").forEach(s=>{s.shadowRoot&&t.push(...E(s.shadowRoot,o));}),t.push(...e.querySelectorAll(o).values()),t}var X=(e,o={})=>{let t=new Map([[e,new Set]]),s=(n,r)=>t.set(n,new Set([...t.get(n)||[],r]));Object.entries(o||{}).forEach(([n,r])=>{typeof r=="boolean"?r&&s(e,`${n}-all`):typeof r=="string"?E(e,r).forEach(c=>s(c,n)):Array.isArray(r)&&r.forEach(c=>E(e,c).forEach(a=>s(a,n)));}),t.forEach((n,r)=>{let c=new Set;n.forEach(a=>{let l=a.replace("-all","");u[a]?c.add(`pseudo-${u[a]}`):u[l]&&c.add(`pseudo-${u[l]}-all`);}),C(r,c);});},D=e=>{let o=new Set;e.className.split(" ").filter(t=>t.match(/^pseudo-(.(?!-all))+$/)).forEach(t=>o.add(t));for(let t=e.parentNode;t;){if(t instanceof ShadowRoot){t=t.host;continue}if(t instanceof Element){let s=t;s.className&&s.className.split(" ").filter(n=>n.match(/^pseudo-.+-all$/)!==null).forEach(n=>o.add(n));}t=t.parentNode;}C(e,o);},$=e=>{let{rootSelector:o,...t}=e||{};return t},V=(e={},o={})=>e!==null&&o!==null&&Object.keys(e).length===Object.keys(o).length&&Object.keys(e).every(t=>JSON.stringify(e[t])===JSON.stringify(o[t])),N=(e,{viewMode:o,parameters:t,id:s,globals:n})=>{let{pseudo:r}=t,{pseudo:c}=n,{rootSelector:a}=r||{},l=previewApi.useMemo(()=>a?document.querySelector(a):o==="docs"?document.getElementById(`story--${s}`):document.getElementById("storybook-root")||document.getElementById("root"),[a,o,s]);return previewApi.useEffect(()=>{let i=$(r);o==="story"&&!V(i,c)&&S.emit(coreEvents.UPDATE_GLOBALS,{globals:{pseudo:i}});},[r,o]),previewApi.useEffect(()=>{if(!l)return;let i=setTimeout(()=>{X(l,c||$(r)),f.forEach(D);},0);return ()=>clearTimeout(i)},[l,c,r]),e()},p=e=>{let o=Array.from(e?e.styleSheets:document.styleSheets);e?.adoptedStyleSheets?.length&&(o=e.adoptedStyleSheets),o.forEach(t=>O(t,!!e)),e&&f&&f.add(e.host);};S.on(coreEvents.STORY_CHANGED,()=>f.clear());S.on(coreEvents.STORY_RENDERED,()=>p());S.on(coreEvents.GLOBALS_UPDATED,()=>p());S.on(coreEvents.FORCE_RE_RENDER,()=>p());S.on(coreEvents.FORCE_REMOUNT,()=>p());S.on(coreEvents.DOCS_RENDERED,()=>p());Element.prototype.attachShadow&&(Element.prototype._attachShadow=Element.prototype.attachShadow,Element.prototype.attachShadow=function(o){let t=this._attachShadow({...o,mode:"open"});return requestAnimationFrame(()=>{p(t),f.has(t.host)&&D(t.host);}),t});var ue=[N],Se={[g]:!1};
|
|
7
7
|
|
|
8
|
-
exports.decorators =
|
|
9
|
-
exports.globals =
|
|
8
|
+
exports.decorators = ue;
|
|
9
|
+
exports.globals = Se;
|
|
10
10
|
//# sourceMappingURL=out.js.map
|
|
11
11
|
//# sourceMappingURL=preview.js.map
|
package/dist/preview.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/preview/withPseudoState.ts","../src/preview/splitSelectors.ts","../src/preview/rewriteStyleSheet.ts","../src/preview.ts"],"names":["ADDON_ID","TOOL_ID","PARAM_KEY","EXCLUDED_PSEUDO_ELEMENTS","PSEUDO_STATES","DOCS_RENDERED","FORCE_REMOUNT","FORCE_RE_RENDER","GLOBALS_UPDATED","STORY_CHANGED","STORY_RENDERED","UPDATE_GLOBALS","addons","useEffect","useMemo","isAtRule","selector","splitSelectors","selectors","result","parentheses","brackets","i","len","char","pseudoStates","matchOne","matchAll","warnings","warnOnce","message","isExcludedPseudoElement","pseudoState","element","rewriteRule","cssText","selectorText","shadowRoot","states","plainSelector","_","state","classSelector","acc","ancestorSelector","statesAllClassSelectors","s","matches","rewriteStyleSheet","sheet","count","rewriteRuleContainer","e","ruleContainer","rewriteLimit","index","cssRule","numRewritten","styleRule","newRule","channel","shadowHosts","applyClasses","classnames","classname","querySelectorPiercingShadowDOM","root","results","el","applyParameter","rootElement","parameter","map","add","target","value","sel","key","keyWithoutAll","updateShadowHost","shadowHost","node","pseudoConfig","rootSelector","pseudoStateConfig","equals","a","b","withPseudoState","StoryFn","viewMode","parameters","id","globalsArgs","globals","config","timeout","rewriteStyleSheets","styleSheets","init","decorators"],"mappings":"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","sourcesContent":["export const ADDON_ID = \"storybook/pseudo-states\"\nexport const TOOL_ID = `${ADDON_ID}/tool`\nexport const PARAM_KEY = \"pseudo\"\n\n// Pseudo-elements which are not allowed to have classes applied on them\n// E.g. ::-webkit-scrollbar-thumb.pseudo-hover is not a valid selector\nexport const EXCLUDED_PSEUDO_ELEMENTS = [\"::-webkit-scrollbar-thumb\", \"::-webkit-slider-thumb\"]\n\n// Dynamic pseudo-classes\n// @see https://www.w3.org/TR/2018/REC-selectors-3-20181106/#dynamic-pseudos\nexport const PSEUDO_STATES = {\n hover: \"hover\",\n active: \"active\",\n focusVisible: \"focus-visible\",\n focusWithin: \"focus-within\",\n focus: \"focus\", // must come after its alternatives\n visited: \"visited\",\n link: \"link\",\n target: \"target\",\n} as const\n\nexport type PseudoState = keyof typeof PSEUDO_STATES\n","/* eslint-env browser */\nimport {\n DOCS_RENDERED,\n FORCE_REMOUNT,\n FORCE_RE_RENDER,\n GLOBALS_UPDATED,\n STORY_CHANGED,\n STORY_RENDERED,\n UPDATE_GLOBALS,\n} from \"@storybook/core-events\"\nimport { DecoratorFunction } from \"@storybook/types\"\nimport { addons, useEffect, useMemo } from \"@storybook/preview-api\"\n\nimport { PSEUDO_STATES, PseudoState } from \"../constants\"\nimport { rewriteStyleSheet } from \"./rewriteStyleSheet\"\n\ntype PseudoStateConfig = {\n [P in PseudoState]?: boolean | string | string[]\n}\n\nexport interface PseudoParameter extends PseudoStateConfig {\n rootSelector?: string\n}\n\nconst channel = addons.getChannel()\nconst shadowHosts = new Set<Element>()\n\n// Drops any existing pseudo state classnames that carried over from a previously viewed story\n// before adding the new classnames. We use forEach for IE compatibility.\nconst applyClasses = (element: Element, classnames: Set<string>) => {\n Object.values(PSEUDO_STATES).forEach((state) => {\n element.classList.remove(`pseudo-${state}`)\n element.classList.remove(`pseudo-${state}-all`)\n })\n classnames.forEach((classname) => element.classList.add(classname))\n}\n\nfunction querySelectorPiercingShadowDOM(root: Element | ShadowRoot, selector: string) {\n const results: Element[] = [];\n root.querySelectorAll('*').forEach((el) => {\n if (el.shadowRoot) {\n results.push(...querySelectorPiercingShadowDOM(el.shadowRoot, selector))\n }\n })\n results.push(...root.querySelectorAll(selector).values())\n return results\n}\n\nconst applyParameter = (rootElement: Element, parameter: PseudoStateConfig = {}) => {\n const map = new Map([[rootElement, new Set<PseudoState>()]])\n const add = (target: Element, state: PseudoState) =>\n map.set(target, new Set([...(map.get(target) || []), state]))\n\n ;(Object.entries(parameter || {}) as [PseudoState, any]).forEach(([state, value]) => {\n if (typeof value === \"boolean\") {\n // default API - applying pseudo class to root element.\n if (value) add(rootElement, `${state}-all` as PseudoState)\n } else if (typeof value === \"string\") {\n // explicit selectors API - applying pseudo class to a specific element\n querySelectorPiercingShadowDOM(rootElement, value).forEach((el) => add(el, state))\n } else if (Array.isArray(value)) {\n // explicit selectors API - we have an array (of strings) recursively handle each one\n value.forEach((sel) => querySelectorPiercingShadowDOM(rootElement, sel).forEach((el) => add(el, state)))\n }\n })\n\n map.forEach((states, target) => {\n const classnames = new Set<string>()\n states.forEach((key) => {\n const keyWithoutAll = key.replace(\"-all\", \"\") as PseudoState\n if (PSEUDO_STATES[key]) {\n classnames.add(`pseudo-${PSEUDO_STATES[key]}`)\n } else if (PSEUDO_STATES[keyWithoutAll]) {\n classnames.add(`pseudo-${PSEUDO_STATES[keyWithoutAll]}-all`)\n }\n })\n applyClasses(target, classnames)\n })\n}\n\n// Traverses ancestry to collect relevant pseudo classnames, and applies them to the shadow host.\n// Shadow DOM can only access classes on its host. Traversing is needed to mimic the CSS cascade.\nconst updateShadowHost = (shadowHost: Element) => {\n const classnames = new Set<string>()\n // Keep any existing \"pseudo-*\" classes\n shadowHost.className\n .split(\" \")\n .filter((classname) => classname.startsWith(\"pseudo-\"))\n .forEach((classname) => classnames.add(classname))\n // Adopt \"pseudo-*-all\" classes from ancestors (across shadow boundaries)\n for (let node = shadowHost.parentNode; node;) {\n if (node instanceof ShadowRoot) {\n node = node.host\n continue\n }\n if (node instanceof Element) {\n const element = node\n if (element.className) {\n element.className\n .split(\" \")\n .filter((classname) => classname.match(/^pseudo-.+-all$/) !== null)\n .forEach((classname) => classnames.add(classname))\n }\n }\n node = node.parentNode\n }\n applyClasses(shadowHost, classnames)\n}\n\n// Drops the rootSelector from the parameter object, as it is not a pseudo state.\nconst pseudoConfig = (parameter: PseudoParameter) => {\n const { rootSelector, ...pseudoStateConfig } = parameter || {}\n return pseudoStateConfig\n}\n\n// Compares two pseudo state configs to see if they are equal.\n// Uses JSON.stringify to handle arrays, so the order of selectors in the array matters.\nconst equals = (a: PseudoStateConfig = {}, b: PseudoStateConfig = {}) =>\n a !== null &&\n b !== null &&\n Object.keys(a).length === Object.keys(b).length &&\n (Object.keys(a) as PseudoState[]).every(\n (key) => JSON.stringify(a[key]) === JSON.stringify(b[key])\n )\n\n// Global decorator that rewrites stylesheets and applies classnames to render pseudo styles\nexport const withPseudoState: DecoratorFunction = (\n StoryFn,\n { viewMode, parameters, id, globals: globalsArgs }\n) => {\n const { pseudo: parameter } = parameters\n const { pseudo: globals } = globalsArgs\n const { rootSelector } = parameter || {}\n\n const rootElement = useMemo(() => {\n if (rootSelector) {\n return document.querySelector(rootSelector)\n }\n if (viewMode === \"docs\") {\n return document.getElementById(`story--${id}`)\n }\n return (\n document.getElementById(\"storybook-root\") || // Storybook 7.0+\n document.getElementById(\"root\")\n )\n }, [rootSelector, viewMode, id])\n\n // Sync parameter to globals, used by the toolbar (only in canvas as this\n // doesn't make sense for docs because many stories are displayed at once)\n useEffect(() => {\n const config = pseudoConfig(parameter)\n if (viewMode === \"story\" && !equals(config, globals)) {\n channel.emit(UPDATE_GLOBALS, {\n globals: { pseudo: config },\n })\n }\n }, [parameter, viewMode])\n\n // Convert selected states to classnames and apply them to the story root element.\n // Then update each shadow host to redetermine its own pseudo classnames.\n useEffect(() => {\n if (!rootElement) return\n const timeout = setTimeout(() => {\n applyParameter(rootElement, globals || pseudoConfig(parameter))\n shadowHosts.forEach(updateShadowHost)\n }, 0)\n return () => clearTimeout(timeout)\n }, [rootElement, globals, parameter])\n\n return StoryFn()\n}\n\n// Rewrite CSS rules for pseudo-states on all stylesheets to add an alternative selector\nconst rewriteStyleSheets = (shadowRoot?: ShadowRoot) => {\n let styleSheets = Array.from(shadowRoot ? shadowRoot.styleSheets : document.styleSheets)\n if (shadowRoot?.adoptedStyleSheets?.length) styleSheets = shadowRoot.adoptedStyleSheets\n const rewroteStyles = styleSheets\n .map((sheet) => rewriteStyleSheet(sheet, shadowRoot))\n .some(Boolean)\n if (rewroteStyles && shadowRoot && shadowHosts) shadowHosts.add(shadowRoot.host)\n}\n\n// Only track shadow hosts for the current story\nchannel.on(STORY_CHANGED, () => shadowHosts.clear())\n\n// Reinitialize CSS enhancements every time the story changes\nchannel.on(STORY_RENDERED, () => rewriteStyleSheets())\nchannel.on(GLOBALS_UPDATED, () => rewriteStyleSheets())\nchannel.on(FORCE_RE_RENDER, () => rewriteStyleSheets())\nchannel.on(FORCE_REMOUNT, () => rewriteStyleSheets())\n\n// Reinitialize CSS enhancements every time a docs page is rendered\nchannel.on(DOCS_RENDERED, () => rewriteStyleSheets())\n\n// IE doesn't support shadow DOM\nif (Element.prototype.attachShadow) {\n // Monkeypatch the attachShadow method so we can handle pseudo styles inside shadow DOM\n // @ts-expect-error (Monkeypatch)\n Element.prototype._attachShadow = Element.prototype.attachShadow\n Element.prototype.attachShadow = function attachShadow(init) {\n // Force \"open\" mode, so we can access the shadowRoot\n // @ts-expect-error (Monkeypatch)\n const shadowRoot = this._attachShadow({ ...init, mode: \"open\" })\n // Wait for it to render and apply its styles before rewriting them\n requestAnimationFrame(() => {\n rewriteStyleSheets(shadowRoot)\n if (shadowHosts.has(shadowRoot.host)) updateShadowHost(shadowRoot.host)\n })\n return shadowRoot\n }\n}\n","const isAtRule = (selector: string) => selector.indexOf(\"@\") === 0\n\nexport const splitSelectors = (selectors: string) => {\n if (isAtRule(selectors)) return [selectors]\n\n let result = []\n let parentheses = 0\n let brackets = 0\n let selector = \"\"\n\n for (let i = 0, len = selectors.length; i < len; i++) {\n const char = selectors[i]\n if (char === \"(\") {\n parentheses += 1\n } else if (char === \")\") {\n parentheses -= 1\n } else if (char === \"[\") {\n brackets += 1\n } else if (char === \"]\") {\n brackets -= 1\n } else if (char === \",\") {\n if (!parentheses && !brackets) {\n result.push(selector.trim())\n selector = \"\"\n continue\n }\n }\n selector += char\n }\n\n result.push(selector.trim())\n return result\n}\n","import { PSEUDO_STATES, EXCLUDED_PSEUDO_ELEMENTS } from \"../constants\"\nimport { splitSelectors } from \"./splitSelectors\"\n\nconst pseudoStates = Object.values(PSEUDO_STATES)\nconst matchOne = new RegExp(`:(${pseudoStates.join(\"|\")})`)\nconst matchAll = new RegExp(`:(${pseudoStates.join(\"|\")})`, \"g\")\n\nconst warnings = new Set()\nconst warnOnce = (message: string) => {\n if (warnings.has(message)) return\n // eslint-disable-next-line no-console\n console.warn(message)\n warnings.add(message)\n}\n\nconst isExcludedPseudoElement = (selector: string, pseudoState: string) =>\n EXCLUDED_PSEUDO_ELEMENTS.some((element) => selector.endsWith(`${element}:${pseudoState}`))\n\nconst rewriteRule = ({ cssText, selectorText }: CSSStyleRule, shadowRoot?: ShadowRoot) => {\n return cssText.replace(\n selectorText,\n splitSelectors(selectorText)\n .flatMap((selector) => {\n if (selector.includes(\".pseudo-\")) {\n return []\n }\n if (!matchOne.test(selector)) {\n return [selector]\n }\n\n const states: string[] = []\n let plainSelector = selector.replace(matchAll, (_, state) => {\n states.push(state)\n return \"\"\n })\n const classSelector = states.reduce((acc, state) => {\n if (isExcludedPseudoElement(selector, state)) return \"\"\n return acc.replace(new RegExp(`:${state}`, \"g\"), `.pseudo-${state}`)\n }, selector)\n\n let ancestorSelector = \"\"\n const statesAllClassSelectors = states.map((s) => `.pseudo-${s}-all`).join(\"\")\n \n if (selector.startsWith(\":host(\")) {\n const matches = selector.match(/^:host\\(([^ ]+)\\) /)\n if (matches && !matchOne.test(matches[1])) {\n // If :host() did not contain states, then simple replacement won't work.\n ancestorSelector = `:host(${matches[1]}${statesAllClassSelectors}) ${plainSelector.replace(matches[0], \"\")}`\n } else {\n ancestorSelector = states.reduce((acc, state) => {\n if (isExcludedPseudoElement(selector, state)) return \"\"\n return acc.replace(new RegExp(`:${state}`, \"g\"), `.pseudo-${state}-all`)\n }, selector)\n }\n } else if (selector.startsWith(\"::slotted(\") || shadowRoot) {\n if (plainSelector.startsWith(\"::slotted()\")) {\n plainSelector = plainSelector.replace(\"::slotted()\", \"::slotted(*)\")\n }\n ancestorSelector = `:host(${statesAllClassSelectors}) ${plainSelector}`\n } else {\n ancestorSelector = `${statesAllClassSelectors} ${plainSelector}`\n }\n\n return [selector, classSelector, ancestorSelector].filter(\n (selector) => selector && !selector.includes(\":not()\") && !selector.includes(\":has()\")\n )\n })\n .join(\", \")\n )\n}\n\n// Rewrites the style sheet to add alternative selectors for any rule that targets a pseudo state.\n// A sheet can only be rewritten once, and may carry over between stories.\nexport const rewriteStyleSheet = (\n sheet: CSSStyleSheet,\n shadowRoot?: ShadowRoot\n): boolean => {\n try {\n const maximumRulesToRewrite = 1000\n const count = rewriteRuleContainer(sheet, maximumRulesToRewrite, shadowRoot);\n \n if (count >= maximumRulesToRewrite) {\n warnOnce(\"Reached maximum of 1000 pseudo selectors per sheet, skipping the rest.\")\n }\n\n return count > 0\n } catch (e) {\n if (String(e).includes(\"cssRules\")) {\n warnOnce(`Can't access cssRules, likely due to CORS restrictions: ${sheet.href}`)\n } else {\n // eslint-disable-next-line no-console\n console.error(e, sheet.href)\n }\n return false\n }\n}\n\nconst rewriteRuleContainer = (\n ruleContainer: CSSStyleSheet | CSSGroupingRule,\n rewriteLimit: number,\n shadowRoot?: ShadowRoot\n): number => {\n let count = 0\n let index = -1\n for (const cssRule of ruleContainer.cssRules) {\n index++\n let numRewritten = 0\n\n // @ts-expect-error\n if (cssRule.__processed) {\n // @ts-expect-error\n numRewritten = cssRule.__pseudoStatesRewrittenCount\n } else {\n if (\"cssRules\" in cssRule && (cssRule.cssRules as CSSRuleList).length) {\n numRewritten = rewriteRuleContainer(cssRule as CSSGroupingRule, rewriteLimit - count, shadowRoot)\n } else {\n if (!(\"selectorText\" in cssRule)) continue\n const styleRule = cssRule as CSSStyleRule\n if (matchOne.test(styleRule.selectorText)) {\n const newRule = rewriteRule(styleRule, shadowRoot)\n ruleContainer.deleteRule(index)\n ruleContainer.insertRule(newRule, index)\n numRewritten = 1\n }\n }\n // @ts-expect-error\n cssRule.__processed = true\n // @ts-expect-error\n cssRule.__pseudoStatesRewrittenCount = numRewritten\n }\n count += numRewritten\n\n if (count >= rewriteLimit) {\n break\n }\n }\n\n return count\n}\n","import { PARAM_KEY } from \"./constants\"\nimport { withPseudoState } from \"./preview/withPseudoState\"\n\nexport const decorators = [withPseudoState]\nexport const globals = { [PARAM_KEY]: false }\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/preview/withPseudoState.ts","../src/preview/splitSelectors.ts","../src/preview/rewriteStyleSheet.ts","../src/preview.ts"],"names":["ADDON_ID","TOOL_ID","PARAM_KEY","EXCLUDED_PSEUDO_ELEMENT_PATTERNS","PSEUDO_STATES","DOCS_RENDERED","FORCE_REMOUNT","FORCE_RE_RENDER","GLOBALS_UPDATED","STORY_CHANGED","STORY_RENDERED","UPDATE_GLOBALS","addons","useEffect","useMemo","isAtRule","selector","splitSelectors","selectors","result","parentheses","brackets","i","len","char","pseudoStates","pseudoStatesPattern","matchOne","matchAll","warnings","warnOnce","message","replacePseudoStates","allClass","negativeLookbehind","acc","state","replacePseudoStatesWithAncestorSelector","forShadowDOM","additionalHostSelectors","states","withoutPseudoStates","extractPseudoStates","s","_","rewriteNotSelectors","match","originalNot","selectorList","rewrittenNot","rewriteNotSelector","negatedSelectorList","rewrittenSelectors","negatedSelector","rewriteRule","cssText","selectorText","replacementSelectors","classSelector","ancestorSelector","matches","hostInnerSelector","descendantSelector","withNotsReplaced","rewriteStyleSheet","sheet","count","rewriteRuleContainer","e","ruleContainer","rewriteLimit","index","cssRule","numRewritten","styleRule","newRule","channel","shadowHosts","applyClasses","element","classnames","classname","querySelectorPiercingShadowDOM","root","results","el","applyParameter","rootElement","parameter","map","add","target","value","sel","key","keyWithoutAll","updateShadowHost","shadowHost","node","pseudoConfig","rootSelector","pseudoStateConfig","equals","a","b","withPseudoState","StoryFn","viewMode","parameters","id","globalsArgs","globals","config","timeout","rewriteStyleSheets","shadowRoot","styleSheets","init","decorators"],"mappings":"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","sourcesContent":["export const ADDON_ID = \"storybook/pseudo-states\"\nexport const TOOL_ID = `${ADDON_ID}/tool`\nexport const PARAM_KEY = \"pseudo\"\n\n// Regex patterns for pseudo-elements which are not allowed to have classes applied on them\n// E.g. ::-webkit-scrollbar-thumb.pseudo-hover is not a valid selector\nexport const EXCLUDED_PSEUDO_ELEMENT_PATTERNS = [\"::-webkit-scrollbar-thumb\", \"::-webkit-slider-thumb\", \"::part\\\\([^)]+\\\\)\"]\n\n// Dynamic pseudo-classes\n// @see https://www.w3.org/TR/2018/REC-selectors-3-20181106/#dynamic-pseudos\nexport const PSEUDO_STATES = {\n hover: \"hover\",\n active: \"active\",\n focusVisible: \"focus-visible\",\n focusWithin: \"focus-within\",\n focus: \"focus\", // must come after its alternatives\n visited: \"visited\",\n link: \"link\",\n target: \"target\",\n} as const\n\nexport type PseudoState = keyof typeof PSEUDO_STATES\n","/* eslint-env browser */\nimport {\n DOCS_RENDERED,\n FORCE_REMOUNT,\n FORCE_RE_RENDER,\n GLOBALS_UPDATED,\n STORY_CHANGED,\n STORY_RENDERED,\n UPDATE_GLOBALS,\n} from \"@storybook/core-events\"\nimport { DecoratorFunction } from \"@storybook/types\"\nimport { addons, useEffect, useMemo } from \"@storybook/preview-api\"\n\nimport { PSEUDO_STATES, PseudoState } from \"../constants\"\nimport { rewriteStyleSheet } from \"./rewriteStyleSheet\"\n\ntype PseudoStateConfig = {\n [P in PseudoState]?: boolean | string | string[]\n}\n\nexport interface PseudoParameter extends PseudoStateConfig {\n rootSelector?: string\n}\n\nconst channel = addons.getChannel()\nconst shadowHosts = new Set<Element>()\n\n// Drops any existing pseudo state classnames that carried over from a previously viewed story\n// before adding the new classnames. We use forEach for IE compatibility.\nconst applyClasses = (element: Element, classnames: Set<string>) => {\n Object.values(PSEUDO_STATES).forEach((state) => {\n element.classList.remove(`pseudo-${state}`)\n element.classList.remove(`pseudo-${state}-all`)\n })\n classnames.forEach((classname) => element.classList.add(classname))\n}\n\nfunction querySelectorPiercingShadowDOM(root: Element | ShadowRoot, selector: string) {\n const results: Element[] = [];\n root.querySelectorAll('*').forEach((el) => {\n if (el.shadowRoot) {\n results.push(...querySelectorPiercingShadowDOM(el.shadowRoot, selector))\n }\n })\n results.push(...root.querySelectorAll(selector).values())\n return results\n}\n\nconst applyParameter = (rootElement: Element, parameter: PseudoStateConfig = {}) => {\n const map = new Map([[rootElement, new Set<PseudoState>()]])\n const add = (target: Element, state: PseudoState) =>\n map.set(target, new Set([...(map.get(target) || []), state]))\n\n ;(Object.entries(parameter || {}) as [PseudoState, any]).forEach(([state, value]) => {\n if (typeof value === \"boolean\") {\n // default API - applying pseudo class to root element.\n if (value) add(rootElement, `${state}-all` as PseudoState)\n } else if (typeof value === \"string\") {\n // explicit selectors API - applying pseudo class to a specific element\n querySelectorPiercingShadowDOM(rootElement, value).forEach((el) => add(el, state))\n } else if (Array.isArray(value)) {\n // explicit selectors API - we have an array (of strings) recursively handle each one\n value.forEach((sel) => querySelectorPiercingShadowDOM(rootElement, sel).forEach((el) => add(el, state)))\n }\n })\n\n map.forEach((states, target) => {\n const classnames = new Set<string>()\n states.forEach((key) => {\n const keyWithoutAll = key.replace(\"-all\", \"\") as PseudoState\n if (PSEUDO_STATES[key]) {\n classnames.add(`pseudo-${PSEUDO_STATES[key]}`)\n } else if (PSEUDO_STATES[keyWithoutAll]) {\n classnames.add(`pseudo-${PSEUDO_STATES[keyWithoutAll]}-all`)\n }\n })\n applyClasses(target, classnames)\n })\n}\n\n// Traverses ancestry to collect relevant pseudo classnames, and applies them to the shadow host.\n// Shadow DOM can only access classes on its host. Traversing is needed to mimic the CSS cascade.\nconst updateShadowHost = (shadowHost: Element) => {\n const classnames = new Set<string>()\n // Keep any existing \"pseudo-*\" classes (but not \"pseudo-*-all\").\n // \"pseudo-*-all\" classes may be stale and will be re-added as needed.\n shadowHost.className\n .split(\" \")\n .filter((classname) => classname.match(/^pseudo-(.(?!-all))+$/))\n .forEach((classname) => classnames.add(classname))\n // Adopt \"pseudo-*-all\" classes from ancestors (across shadow boundaries)\n for (let node = shadowHost.parentNode; node;) {\n if (node instanceof ShadowRoot) {\n node = node.host\n continue\n }\n if (node instanceof Element) {\n const element = node\n if (element.className) {\n element.className\n .split(\" \")\n .filter((classname) => classname.match(/^pseudo-.+-all$/) !== null)\n .forEach((classname) => classnames.add(classname))\n }\n }\n node = node.parentNode\n }\n applyClasses(shadowHost, classnames)\n}\n\n// Drops the rootSelector from the parameter object, as it is not a pseudo state.\nconst pseudoConfig = (parameter: PseudoParameter) => {\n const { rootSelector, ...pseudoStateConfig } = parameter || {}\n return pseudoStateConfig\n}\n\n// Compares two pseudo state configs to see if they are equal.\n// Uses JSON.stringify to handle arrays, so the order of selectors in the array matters.\nconst equals = (a: PseudoStateConfig = {}, b: PseudoStateConfig = {}) =>\n a !== null &&\n b !== null &&\n Object.keys(a).length === Object.keys(b).length &&\n (Object.keys(a) as PseudoState[]).every(\n (key) => JSON.stringify(a[key]) === JSON.stringify(b[key])\n )\n\n// Global decorator that rewrites stylesheets and applies classnames to render pseudo styles\nexport const withPseudoState: DecoratorFunction = (\n StoryFn,\n { viewMode, parameters, id, globals: globalsArgs }\n) => {\n const { pseudo: parameter } = parameters\n const { pseudo: globals } = globalsArgs\n const { rootSelector } = parameter || {}\n\n const rootElement = useMemo(() => {\n if (rootSelector) {\n return document.querySelector(rootSelector)\n }\n if (viewMode === \"docs\") {\n return document.getElementById(`story--${id}`)\n }\n return (\n document.getElementById(\"storybook-root\") || // Storybook 7.0+\n document.getElementById(\"root\")\n )\n }, [rootSelector, viewMode, id])\n\n // Sync parameter to globals, used by the toolbar (only in canvas as this\n // doesn't make sense for docs because many stories are displayed at once)\n useEffect(() => {\n const config = pseudoConfig(parameter)\n if (viewMode === \"story\" && !equals(config, globals)) {\n channel.emit(UPDATE_GLOBALS, {\n globals: { pseudo: config },\n })\n }\n }, [parameter, viewMode])\n\n // Convert selected states to classnames and apply them to the story root element.\n // Then update each shadow host to redetermine its own pseudo classnames.\n useEffect(() => {\n if (!rootElement) return\n const timeout = setTimeout(() => {\n applyParameter(rootElement, globals || pseudoConfig(parameter))\n shadowHosts.forEach(updateShadowHost)\n }, 0)\n return () => clearTimeout(timeout)\n }, [rootElement, globals, parameter])\n\n return StoryFn()\n}\n\n// Rewrite CSS rules for pseudo-states on all stylesheets to add an alternative selector\nconst rewriteStyleSheets = (shadowRoot?: ShadowRoot) => {\n let styleSheets = Array.from(shadowRoot ? shadowRoot.styleSheets : document.styleSheets)\n if (shadowRoot?.adoptedStyleSheets?.length) styleSheets = shadowRoot.adoptedStyleSheets\n styleSheets.forEach((sheet) => rewriteStyleSheet(sheet, !!shadowRoot))\n if (shadowRoot && shadowHosts) shadowHosts.add(shadowRoot.host)\n}\n\n// Only track shadow hosts for the current story\nchannel.on(STORY_CHANGED, () => shadowHosts.clear())\n\n// Reinitialize CSS enhancements every time the story changes\nchannel.on(STORY_RENDERED, () => rewriteStyleSheets())\nchannel.on(GLOBALS_UPDATED, () => rewriteStyleSheets())\nchannel.on(FORCE_RE_RENDER, () => rewriteStyleSheets())\nchannel.on(FORCE_REMOUNT, () => rewriteStyleSheets())\n\n// Reinitialize CSS enhancements every time a docs page is rendered\nchannel.on(DOCS_RENDERED, () => rewriteStyleSheets())\n\n// IE doesn't support shadow DOM\nif (Element.prototype.attachShadow) {\n // Monkeypatch the attachShadow method so we can handle pseudo styles inside shadow DOM\n // @ts-expect-error (Monkeypatch)\n Element.prototype._attachShadow = Element.prototype.attachShadow\n Element.prototype.attachShadow = function attachShadow(init) {\n // Force \"open\" mode, so we can access the shadowRoot\n // @ts-expect-error (Monkeypatch)\n const shadowRoot = this._attachShadow({ ...init, mode: \"open\" })\n // Wait for it to render and apply its styles before rewriting them\n requestAnimationFrame(() => {\n rewriteStyleSheets(shadowRoot)\n if (shadowHosts.has(shadowRoot.host)) updateShadowHost(shadowRoot.host)\n })\n return shadowRoot\n }\n}\n","const isAtRule = (selector: string) => selector.indexOf(\"@\") === 0\n\nexport const splitSelectors = (selectors: string) => {\n if (isAtRule(selectors)) return [selectors]\n\n let result = []\n let parentheses = 0\n let brackets = 0\n let selector = \"\"\n\n for (let i = 0, len = selectors.length; i < len; i++) {\n const char = selectors[i]\n if (char === \"(\") {\n parentheses += 1\n } else if (char === \")\") {\n parentheses -= 1\n } else if (char === \"[\") {\n brackets += 1\n } else if (char === \"]\") {\n brackets -= 1\n } else if (char === \",\") {\n if (!parentheses && !brackets) {\n result.push(selector.trim())\n selector = \"\"\n continue\n }\n }\n selector += char\n }\n\n result.push(selector.trim())\n return result\n}\n","import { PSEUDO_STATES, EXCLUDED_PSEUDO_ELEMENT_PATTERNS } from \"../constants\"\nimport { splitSelectors } from \"./splitSelectors\"\n\nconst pseudoStates = Object.values(PSEUDO_STATES)\nconst pseudoStatesPattern = `:(${pseudoStates.join(\"|\")})`\nconst matchOne = new RegExp(pseudoStatesPattern)\nconst matchAll = new RegExp(pseudoStatesPattern, \"g\")\n \nconst warnings = new Set()\nconst warnOnce = (message: string) => {\n if (warnings.has(message)) return\n // eslint-disable-next-line no-console\n console.warn(message)\n warnings.add(message)\n}\n\nconst replacePseudoStates = (selector: string, allClass?: boolean) => {\n const negativeLookbehind = `(?<!(?:${EXCLUDED_PSEUDO_ELEMENT_PATTERNS.join(\"|\")})\\\\S*)`\n return pseudoStates.reduce((acc, state) => acc.replace(\n new RegExp(`${negativeLookbehind}:${state}`, \"g\"), \n `.pseudo-${state}${allClass ? \"-all\" : \"\"}`\n ), selector)\n}\n\n// Does not handle :host() or :not() containing pseudo-states. Need to call replaceNotSelectors on the input first.\nconst replacePseudoStatesWithAncestorSelector = (selector: string, forShadowDOM: boolean, additionalHostSelectors?: string) => {\n let { states, withoutPseudoStates } = extractPseudoStates(selector)\n if (states.length === 0 && !additionalHostSelectors) {\n return selector\n }\n const selectors = `${additionalHostSelectors ?? \"\"}${states.map((s) => `.pseudo-${s}-all`).join(\"\")}`\n\n // If there was a :host-context() containing only pseudo-states, we will later add a :host selector that replaces it.\n withoutPseudoStates = withoutPseudoStates.replace(\":host-context(*)\", \"\").trimStart()\n\n // If there is a :host-context() selector, we don't need to introduce a :host() selector.\n // We can just append the pseudo-state classes to the :host-context() selector.\n return withoutPseudoStates.startsWith(\":host-context(\")\n ? withoutPseudoStates.replace(/(?<=:host-context\\(\\S+)\\)/, `)${selectors}`)\n : forShadowDOM\n ? `:host(${selectors}) ${withoutPseudoStates}`\n : `${selectors} ${withoutPseudoStates}`\n}\n\nconst extractPseudoStates = (selector: string) => {\n const states = new Set()\n const withoutPseudoStates = selector\n .replace(matchAll, (_, state) => {\n states.add(state)\n return \"\"\n })\n // If removing pseudo-state selectors from inside a functional selector left it empty (thus invalid), must fix it by adding '*'.\n .replaceAll(\"()\", \"(*)\")\n // If a selector list was left with blank items (e.g. \", foo, , bar, \"), remove the extra commas/spaces.\n .replace(/(?<=[\\s(]),\\s+|(,\\s+)+(?=\\))/g, \"\") || \"*\"\n\n return {\n states: Array.from(states),\n withoutPseudoStates\n }\n}\n\nconst rewriteNotSelectors = (selector: string, forShadowDOM: boolean) => {\n return [...selector.matchAll(/:not\\(([^)]+)\\)/g)].reduce((acc, match) => {\n const originalNot = match[0]\n const selectorList = match[1]\n const rewrittenNot = rewriteNotSelector(selectorList, forShadowDOM)\n return acc.replace(originalNot, rewrittenNot)\n }, selector)\n}\n\nconst rewriteNotSelector = (negatedSelectorList: string, forShadowDOM: boolean) => {\n const rewrittenSelectors: string[] = []\n // For each negated selector\n for (const negatedSelector of negatedSelectorList.split(/,\\s*/)) {\n // :not cannot be nested and cannot contain pseudo-elements, so no need to worry about that.\n // Also, there's no compelling use case for :host() inside :not(), so we don't handle that.\n rewrittenSelectors.push(replacePseudoStatesWithAncestorSelector(negatedSelector, forShadowDOM))\n }\n return `:not(${rewrittenSelectors.join(\", \")})`\n}\n\nconst rewriteRule = ({ cssText, selectorText }: CSSStyleRule, forShadowDOM: boolean) => {\n return cssText.replace(\n selectorText,\n splitSelectors(selectorText)\n .flatMap((selector) => {\n if (selector.includes(\".pseudo-\")) {\n return []\n }\n const replacementSelectors = [selector]\n if (!matchOne.test(selector)) {\n return replacementSelectors\n }\n\n const classSelector = replacePseudoStates(selector)\n if (classSelector !== selector) {\n replacementSelectors.push(classSelector)\n }\n\n let ancestorSelector = \"\"\n \n if (selector.startsWith(\":host(\")) {\n const matches = selector.match(/^:host\\((\\S+)\\)\\s+(.+)$/)\n if (matches && matchOne.test(matches[2])) {\n // Simple replacement won't work on pseudo-state selectors outside of :host().\n // E.g. :host(.foo) .bar:hover -> :host(.foo.pseudo-hover-all) .bar\n // E.g. :host(.foo:focus) .bar:hover -> :host(.foo.pseudo-focus-all.pseudo-hover-all) .bar\n let hostInnerSelector = matches[1]\n let descendantSelector = matches[2]\n // Simple replacement is fine for pseudo-state selectors inside :host() (even if inside :not()).\n hostInnerSelector = replacePseudoStates(hostInnerSelector, true)\n // Rewrite any :not selectors in the descendant selector.\n descendantSelector = rewriteNotSelectors(descendantSelector, true)\n // Any remaining pseudo-states in the descendant selector need to be moved into the host selector.\n ancestorSelector = replacePseudoStatesWithAncestorSelector(descendantSelector, true, hostInnerSelector)\n } else {\n // Don't need to specially handle :not() because:\n // - if inside :host(), simple replacement is sufficient\n // - if outside :host(), didn't match any pseudo-states\n ancestorSelector = replacePseudoStates(selector, true)\n }\n } else {\n const withNotsReplaced = rewriteNotSelectors(selector, forShadowDOM)\n ancestorSelector = replacePseudoStatesWithAncestorSelector(withNotsReplaced, forShadowDOM)\n }\n replacementSelectors.push(ancestorSelector)\n\n return replacementSelectors\n })\n .join(\", \")\n )\n}\n\n// Rewrites the style sheet to add alternative selectors for any rule that targets a pseudo state.\n// A sheet can only be rewritten once, and may carry over between stories.\nexport const rewriteStyleSheet = (\n sheet: CSSStyleSheet,\n forShadowDOM = false\n): boolean => {\n try {\n const maximumRulesToRewrite = 1000\n const count = rewriteRuleContainer(sheet, maximumRulesToRewrite, forShadowDOM);\n \n if (count >= maximumRulesToRewrite) {\n warnOnce(\"Reached maximum of 1000 pseudo selectors per sheet, skipping the rest.\")\n }\n\n return count > 0\n } catch (e) {\n if (String(e).includes(\"cssRules\")) {\n warnOnce(`Can't access cssRules, likely due to CORS restrictions: ${sheet.href}`)\n } else {\n // eslint-disable-next-line no-console\n console.error(e, sheet.href)\n }\n return false\n }\n}\n\nconst rewriteRuleContainer = (\n ruleContainer: CSSStyleSheet | CSSGroupingRule,\n rewriteLimit: number,\n forShadowDOM: boolean\n): number => {\n let count = 0\n let index = -1\n for (const cssRule of ruleContainer.cssRules) {\n index++\n let numRewritten = 0\n\n // @ts-expect-error\n if (cssRule.__processed) {\n // @ts-expect-error\n numRewritten = cssRule.__pseudoStatesRewrittenCount\n } else {\n if (\"cssRules\" in cssRule && (cssRule.cssRules as CSSRuleList).length) {\n numRewritten = rewriteRuleContainer(cssRule as CSSGroupingRule, rewriteLimit - count, forShadowDOM)\n } else {\n if (!(\"selectorText\" in cssRule)) continue\n const styleRule = cssRule as CSSStyleRule\n if (matchOne.test(styleRule.selectorText)) {\n const newRule = rewriteRule(styleRule, forShadowDOM)\n ruleContainer.deleteRule(index)\n ruleContainer.insertRule(newRule, index)\n numRewritten = 1\n }\n }\n // @ts-expect-error\n cssRule.__processed = true\n // @ts-expect-error\n cssRule.__pseudoStatesRewrittenCount = numRewritten\n }\n count += numRewritten\n\n if (count >= rewriteLimit) {\n break\n }\n }\n\n return count\n}\n","import { PARAM_KEY } from \"./constants\"\nimport { withPseudoState } from \"./preview/withPseudoState\"\n\nexport const decorators = [withPseudoState]\nexport const globals = { [PARAM_KEY]: false }\n"]}
|
package/dist/preview.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { STORY_CHANGED, STORY_RENDERED, GLOBALS_UPDATED, FORCE_RE_RENDER, FORCE_REMOUNT, DOCS_RENDERED, UPDATE_GLOBALS } from '@storybook/core-events';
|
|
2
2
|
import { addons, useMemo, useEffect } from '@storybook/preview-api';
|
|
3
3
|
|
|
4
|
-
var g="pseudo",R=["::-webkit-scrollbar-thumb","::-webkit-slider-thumb"],u={hover:"hover",active:"active",focusVisible:"focus-visible",focusWithin:"focus-within",focus:"focus",visited:"visited",link:"link",target:"target"};var k=e=>e.indexOf("@")===0,y=e=>{if(k(e))return [e];let o=[],t=0,s=0,
|
|
4
|
+
var g="pseudo",R=["::-webkit-scrollbar-thumb","::-webkit-slider-thumb","::part\\([^)]+\\)"],u={hover:"hover",active:"active",focusVisible:"focus-visible",focusWithin:"focus-within",focus:"focus",visited:"visited",link:"link",target:"target"};var k=e=>e.indexOf("@")===0,y=e=>{if(k(e))return [e];let o=[],t=0,s=0,n="";for(let r=0,c=e.length;r<c;r++){let a=e[r];if(a==="(")t+=1;else if(a===")")t-=1;else if(a==="[")s+=1;else if(a==="]")s-=1;else if(a===","&&!t&&!s){o.push(n.trim()),n="";continue}n+=a;}return o.push(n.trim()),o};var b=Object.values(u),A=`:(${b.join("|")})`,h=new RegExp(A),j=new RegExp(A,"g"),P=new Set,w=e=>{P.has(e)||(console.warn(e),P.add(e));},d=(e,o)=>{let t=`(?<!(?:${R.join("|")})\\S*)`;return b.reduce((s,n)=>s.replace(new RegExp(`${t}:${n}`,"g"),`.pseudo-${n}${o?"-all":""}`),e)},m=(e,o,t)=>{let{states:s,withoutPseudoStates:n}=U(e);if(s.length===0&&!t)return e;let r=`${t??""}${s.map(c=>`.pseudo-${c}-all`).join("")}`;return n=n.replace(":host-context(*)","").trimStart(),n.startsWith(":host-context(")?n.replace(new RegExp("(?<=:host-context\\(\\S+)\\)"),`)${r}`):o?`:host(${r}) ${n}`:`${r} ${n}`},U=e=>{let o=new Set,t=e.replace(j,(s,n)=>(o.add(n),"")).replaceAll("()","(*)").replace(new RegExp("(?<=[\\s(]),\\s+|(,\\s+)+(?=\\))","g"),"")||"*";return {states:Array.from(o),withoutPseudoStates:t}},_=(e,o)=>[...e.matchAll(/:not\(([^)]+)\)/g)].reduce((t,s)=>{let n=s[0],r=s[1],c=q(r,o);return t.replace(n,c)},e),q=(e,o)=>{let t=[];for(let s of e.split(/,\s*/))t.push(m(s,o));return `:not(${t.join(", ")})`},v=({cssText:e,selectorText:o},t)=>e.replace(o,y(o).flatMap(s=>{if(s.includes(".pseudo-"))return [];let n=[s];if(!h.test(s))return n;let r=d(s);r!==s&&n.push(r);let c="";if(s.startsWith(":host(")){let a=s.match(/^:host\((\S+)\)\s+(.+)$/);if(a&&h.test(a[2])){let l=a[1],i=a[2];l=d(l,!0),i=_(i,!0),c=m(i,!0,l);}else c=d(s,!0);}else {let a=_(s,t);c=m(a,t);}return n.push(c),n}).join(", ")),O=(e,o=!1)=>{try{let s=x(e,1e3,o);return s>=1e3&&w("Reached maximum of 1000 pseudo selectors per sheet, skipping the rest."),s>0}catch(t){return String(t).includes("cssRules")?w(`Can't access cssRules, likely due to CORS restrictions: ${e.href}`):console.error(t,e.href),!1}},x=(e,o,t)=>{let s=0,n=-1;for(let r of e.cssRules){n++;let c=0;if(r.__processed)c=r.__pseudoStatesRewrittenCount;else {if("cssRules"in r&&r.cssRules.length)c=x(r,o-s,t);else {if(!("selectorText"in r))continue;let a=r;if(h.test(a.selectorText)){let l=v(a,t);e.deleteRule(n),e.insertRule(l,n),c=1;}}r.__processed=!0,r.__pseudoStatesRewrittenCount=c;}if(s+=c,s>=o)break}return s};var S=addons.getChannel(),f=new Set,C=(e,o)=>{Object.values(u).forEach(t=>{e.classList.remove(`pseudo-${t}`),e.classList.remove(`pseudo-${t}-all`);}),o.forEach(t=>e.classList.add(t));};function E(e,o){let t=[];return e.querySelectorAll("*").forEach(s=>{s.shadowRoot&&t.push(...E(s.shadowRoot,o));}),t.push(...e.querySelectorAll(o).values()),t}var X=(e,o={})=>{let t=new Map([[e,new Set]]),s=(n,r)=>t.set(n,new Set([...t.get(n)||[],r]));Object.entries(o||{}).forEach(([n,r])=>{typeof r=="boolean"?r&&s(e,`${n}-all`):typeof r=="string"?E(e,r).forEach(c=>s(c,n)):Array.isArray(r)&&r.forEach(c=>E(e,c).forEach(a=>s(a,n)));}),t.forEach((n,r)=>{let c=new Set;n.forEach(a=>{let l=a.replace("-all","");u[a]?c.add(`pseudo-${u[a]}`):u[l]&&c.add(`pseudo-${u[l]}-all`);}),C(r,c);});},D=e=>{let o=new Set;e.className.split(" ").filter(t=>t.match(/^pseudo-(.(?!-all))+$/)).forEach(t=>o.add(t));for(let t=e.parentNode;t;){if(t instanceof ShadowRoot){t=t.host;continue}if(t instanceof Element){let s=t;s.className&&s.className.split(" ").filter(n=>n.match(/^pseudo-.+-all$/)!==null).forEach(n=>o.add(n));}t=t.parentNode;}C(e,o);},$=e=>{let{rootSelector:o,...t}=e||{};return t},V=(e={},o={})=>e!==null&&o!==null&&Object.keys(e).length===Object.keys(o).length&&Object.keys(e).every(t=>JSON.stringify(e[t])===JSON.stringify(o[t])),N=(e,{viewMode:o,parameters:t,id:s,globals:n})=>{let{pseudo:r}=t,{pseudo:c}=n,{rootSelector:a}=r||{},l=useMemo(()=>a?document.querySelector(a):o==="docs"?document.getElementById(`story--${s}`):document.getElementById("storybook-root")||document.getElementById("root"),[a,o,s]);return useEffect(()=>{let i=$(r);o==="story"&&!V(i,c)&&S.emit(UPDATE_GLOBALS,{globals:{pseudo:i}});},[r,o]),useEffect(()=>{if(!l)return;let i=setTimeout(()=>{X(l,c||$(r)),f.forEach(D);},0);return ()=>clearTimeout(i)},[l,c,r]),e()},p=e=>{let o=Array.from(e?e.styleSheets:document.styleSheets);e?.adoptedStyleSheets?.length&&(o=e.adoptedStyleSheets),o.forEach(t=>O(t,!!e)),e&&f&&f.add(e.host);};S.on(STORY_CHANGED,()=>f.clear());S.on(STORY_RENDERED,()=>p());S.on(GLOBALS_UPDATED,()=>p());S.on(FORCE_RE_RENDER,()=>p());S.on(FORCE_REMOUNT,()=>p());S.on(DOCS_RENDERED,()=>p());Element.prototype.attachShadow&&(Element.prototype._attachShadow=Element.prototype.attachShadow,Element.prototype.attachShadow=function(o){let t=this._attachShadow({...o,mode:"open"});return requestAnimationFrame(()=>{p(t),f.has(t.host)&&D(t.host);}),t});var ue=[N],Se={[g]:!1};
|
|
5
5
|
|
|
6
|
-
export {
|
|
6
|
+
export { ue as decorators, Se as globals };
|
|
7
7
|
//# sourceMappingURL=out.js.map
|
|
8
8
|
//# sourceMappingURL=preview.mjs.map
|
package/dist/preview.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/preview/withPseudoState.ts","../src/preview/splitSelectors.ts","../src/preview/rewriteStyleSheet.ts","../src/preview.ts"],"names":["ADDON_ID","TOOL_ID","PARAM_KEY","EXCLUDED_PSEUDO_ELEMENTS","PSEUDO_STATES","DOCS_RENDERED","FORCE_REMOUNT","FORCE_RE_RENDER","GLOBALS_UPDATED","STORY_CHANGED","STORY_RENDERED","UPDATE_GLOBALS","addons","useEffect","useMemo","isAtRule","selector","splitSelectors","selectors","result","parentheses","brackets","i","len","char","pseudoStates","matchOne","matchAll","warnings","warnOnce","message","isExcludedPseudoElement","pseudoState","element","rewriteRule","cssText","selectorText","shadowRoot","states","plainSelector","_","state","classSelector","acc","ancestorSelector","statesAllClassSelectors","s","matches","rewriteStyleSheet","sheet","count","rewriteRuleContainer","e","ruleContainer","rewriteLimit","index","cssRule","numRewritten","styleRule","newRule","channel","shadowHosts","applyClasses","classnames","classname","querySelectorPiercingShadowDOM","root","results","el","applyParameter","rootElement","parameter","map","add","target","value","sel","key","keyWithoutAll","updateShadowHost","shadowHost","node","pseudoConfig","rootSelector","pseudoStateConfig","equals","a","b","withPseudoState","StoryFn","viewMode","parameters","id","globalsArgs","globals","config","timeout","rewriteStyleSheets","styleSheets","init","decorators"],"mappings":"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","sourcesContent":["export const ADDON_ID = \"storybook/pseudo-states\"\nexport const TOOL_ID = `${ADDON_ID}/tool`\nexport const PARAM_KEY = \"pseudo\"\n\n// Pseudo-elements which are not allowed to have classes applied on them\n// E.g. ::-webkit-scrollbar-thumb.pseudo-hover is not a valid selector\nexport const EXCLUDED_PSEUDO_ELEMENTS = [\"::-webkit-scrollbar-thumb\", \"::-webkit-slider-thumb\"]\n\n// Dynamic pseudo-classes\n// @see https://www.w3.org/TR/2018/REC-selectors-3-20181106/#dynamic-pseudos\nexport const PSEUDO_STATES = {\n hover: \"hover\",\n active: \"active\",\n focusVisible: \"focus-visible\",\n focusWithin: \"focus-within\",\n focus: \"focus\", // must come after its alternatives\n visited: \"visited\",\n link: \"link\",\n target: \"target\",\n} as const\n\nexport type PseudoState = keyof typeof PSEUDO_STATES\n","/* eslint-env browser */\nimport {\n DOCS_RENDERED,\n FORCE_REMOUNT,\n FORCE_RE_RENDER,\n GLOBALS_UPDATED,\n STORY_CHANGED,\n STORY_RENDERED,\n UPDATE_GLOBALS,\n} from \"@storybook/core-events\"\nimport { DecoratorFunction } from \"@storybook/types\"\nimport { addons, useEffect, useMemo } from \"@storybook/preview-api\"\n\nimport { PSEUDO_STATES, PseudoState } from \"../constants\"\nimport { rewriteStyleSheet } from \"./rewriteStyleSheet\"\n\ntype PseudoStateConfig = {\n [P in PseudoState]?: boolean | string | string[]\n}\n\nexport interface PseudoParameter extends PseudoStateConfig {\n rootSelector?: string\n}\n\nconst channel = addons.getChannel()\nconst shadowHosts = new Set<Element>()\n\n// Drops any existing pseudo state classnames that carried over from a previously viewed story\n// before adding the new classnames. We use forEach for IE compatibility.\nconst applyClasses = (element: Element, classnames: Set<string>) => {\n Object.values(PSEUDO_STATES).forEach((state) => {\n element.classList.remove(`pseudo-${state}`)\n element.classList.remove(`pseudo-${state}-all`)\n })\n classnames.forEach((classname) => element.classList.add(classname))\n}\n\nfunction querySelectorPiercingShadowDOM(root: Element | ShadowRoot, selector: string) {\n const results: Element[] = [];\n root.querySelectorAll('*').forEach((el) => {\n if (el.shadowRoot) {\n results.push(...querySelectorPiercingShadowDOM(el.shadowRoot, selector))\n }\n })\n results.push(...root.querySelectorAll(selector).values())\n return results\n}\n\nconst applyParameter = (rootElement: Element, parameter: PseudoStateConfig = {}) => {\n const map = new Map([[rootElement, new Set<PseudoState>()]])\n const add = (target: Element, state: PseudoState) =>\n map.set(target, new Set([...(map.get(target) || []), state]))\n\n ;(Object.entries(parameter || {}) as [PseudoState, any]).forEach(([state, value]) => {\n if (typeof value === \"boolean\") {\n // default API - applying pseudo class to root element.\n if (value) add(rootElement, `${state}-all` as PseudoState)\n } else if (typeof value === \"string\") {\n // explicit selectors API - applying pseudo class to a specific element\n querySelectorPiercingShadowDOM(rootElement, value).forEach((el) => add(el, state))\n } else if (Array.isArray(value)) {\n // explicit selectors API - we have an array (of strings) recursively handle each one\n value.forEach((sel) => querySelectorPiercingShadowDOM(rootElement, sel).forEach((el) => add(el, state)))\n }\n })\n\n map.forEach((states, target) => {\n const classnames = new Set<string>()\n states.forEach((key) => {\n const keyWithoutAll = key.replace(\"-all\", \"\") as PseudoState\n if (PSEUDO_STATES[key]) {\n classnames.add(`pseudo-${PSEUDO_STATES[key]}`)\n } else if (PSEUDO_STATES[keyWithoutAll]) {\n classnames.add(`pseudo-${PSEUDO_STATES[keyWithoutAll]}-all`)\n }\n })\n applyClasses(target, classnames)\n })\n}\n\n// Traverses ancestry to collect relevant pseudo classnames, and applies them to the shadow host.\n// Shadow DOM can only access classes on its host. Traversing is needed to mimic the CSS cascade.\nconst updateShadowHost = (shadowHost: Element) => {\n const classnames = new Set<string>()\n // Keep any existing \"pseudo-*\" classes\n shadowHost.className\n .split(\" \")\n .filter((classname) => classname.startsWith(\"pseudo-\"))\n .forEach((classname) => classnames.add(classname))\n // Adopt \"pseudo-*-all\" classes from ancestors (across shadow boundaries)\n for (let node = shadowHost.parentNode; node;) {\n if (node instanceof ShadowRoot) {\n node = node.host\n continue\n }\n if (node instanceof Element) {\n const element = node\n if (element.className) {\n element.className\n .split(\" \")\n .filter((classname) => classname.match(/^pseudo-.+-all$/) !== null)\n .forEach((classname) => classnames.add(classname))\n }\n }\n node = node.parentNode\n }\n applyClasses(shadowHost, classnames)\n}\n\n// Drops the rootSelector from the parameter object, as it is not a pseudo state.\nconst pseudoConfig = (parameter: PseudoParameter) => {\n const { rootSelector, ...pseudoStateConfig } = parameter || {}\n return pseudoStateConfig\n}\n\n// Compares two pseudo state configs to see if they are equal.\n// Uses JSON.stringify to handle arrays, so the order of selectors in the array matters.\nconst equals = (a: PseudoStateConfig = {}, b: PseudoStateConfig = {}) =>\n a !== null &&\n b !== null &&\n Object.keys(a).length === Object.keys(b).length &&\n (Object.keys(a) as PseudoState[]).every(\n (key) => JSON.stringify(a[key]) === JSON.stringify(b[key])\n )\n\n// Global decorator that rewrites stylesheets and applies classnames to render pseudo styles\nexport const withPseudoState: DecoratorFunction = (\n StoryFn,\n { viewMode, parameters, id, globals: globalsArgs }\n) => {\n const { pseudo: parameter } = parameters\n const { pseudo: globals } = globalsArgs\n const { rootSelector } = parameter || {}\n\n const rootElement = useMemo(() => {\n if (rootSelector) {\n return document.querySelector(rootSelector)\n }\n if (viewMode === \"docs\") {\n return document.getElementById(`story--${id}`)\n }\n return (\n document.getElementById(\"storybook-root\") || // Storybook 7.0+\n document.getElementById(\"root\")\n )\n }, [rootSelector, viewMode, id])\n\n // Sync parameter to globals, used by the toolbar (only in canvas as this\n // doesn't make sense for docs because many stories are displayed at once)\n useEffect(() => {\n const config = pseudoConfig(parameter)\n if (viewMode === \"story\" && !equals(config, globals)) {\n channel.emit(UPDATE_GLOBALS, {\n globals: { pseudo: config },\n })\n }\n }, [parameter, viewMode])\n\n // Convert selected states to classnames and apply them to the story root element.\n // Then update each shadow host to redetermine its own pseudo classnames.\n useEffect(() => {\n if (!rootElement) return\n const timeout = setTimeout(() => {\n applyParameter(rootElement, globals || pseudoConfig(parameter))\n shadowHosts.forEach(updateShadowHost)\n }, 0)\n return () => clearTimeout(timeout)\n }, [rootElement, globals, parameter])\n\n return StoryFn()\n}\n\n// Rewrite CSS rules for pseudo-states on all stylesheets to add an alternative selector\nconst rewriteStyleSheets = (shadowRoot?: ShadowRoot) => {\n let styleSheets = Array.from(shadowRoot ? shadowRoot.styleSheets : document.styleSheets)\n if (shadowRoot?.adoptedStyleSheets?.length) styleSheets = shadowRoot.adoptedStyleSheets\n const rewroteStyles = styleSheets\n .map((sheet) => rewriteStyleSheet(sheet, shadowRoot))\n .some(Boolean)\n if (rewroteStyles && shadowRoot && shadowHosts) shadowHosts.add(shadowRoot.host)\n}\n\n// Only track shadow hosts for the current story\nchannel.on(STORY_CHANGED, () => shadowHosts.clear())\n\n// Reinitialize CSS enhancements every time the story changes\nchannel.on(STORY_RENDERED, () => rewriteStyleSheets())\nchannel.on(GLOBALS_UPDATED, () => rewriteStyleSheets())\nchannel.on(FORCE_RE_RENDER, () => rewriteStyleSheets())\nchannel.on(FORCE_REMOUNT, () => rewriteStyleSheets())\n\n// Reinitialize CSS enhancements every time a docs page is rendered\nchannel.on(DOCS_RENDERED, () => rewriteStyleSheets())\n\n// IE doesn't support shadow DOM\nif (Element.prototype.attachShadow) {\n // Monkeypatch the attachShadow method so we can handle pseudo styles inside shadow DOM\n // @ts-expect-error (Monkeypatch)\n Element.prototype._attachShadow = Element.prototype.attachShadow\n Element.prototype.attachShadow = function attachShadow(init) {\n // Force \"open\" mode, so we can access the shadowRoot\n // @ts-expect-error (Monkeypatch)\n const shadowRoot = this._attachShadow({ ...init, mode: \"open\" })\n // Wait for it to render and apply its styles before rewriting them\n requestAnimationFrame(() => {\n rewriteStyleSheets(shadowRoot)\n if (shadowHosts.has(shadowRoot.host)) updateShadowHost(shadowRoot.host)\n })\n return shadowRoot\n }\n}\n","const isAtRule = (selector: string) => selector.indexOf(\"@\") === 0\n\nexport const splitSelectors = (selectors: string) => {\n if (isAtRule(selectors)) return [selectors]\n\n let result = []\n let parentheses = 0\n let brackets = 0\n let selector = \"\"\n\n for (let i = 0, len = selectors.length; i < len; i++) {\n const char = selectors[i]\n if (char === \"(\") {\n parentheses += 1\n } else if (char === \")\") {\n parentheses -= 1\n } else if (char === \"[\") {\n brackets += 1\n } else if (char === \"]\") {\n brackets -= 1\n } else if (char === \",\") {\n if (!parentheses && !brackets) {\n result.push(selector.trim())\n selector = \"\"\n continue\n }\n }\n selector += char\n }\n\n result.push(selector.trim())\n return result\n}\n","import { PSEUDO_STATES, EXCLUDED_PSEUDO_ELEMENTS } from \"../constants\"\nimport { splitSelectors } from \"./splitSelectors\"\n\nconst pseudoStates = Object.values(PSEUDO_STATES)\nconst matchOne = new RegExp(`:(${pseudoStates.join(\"|\")})`)\nconst matchAll = new RegExp(`:(${pseudoStates.join(\"|\")})`, \"g\")\n\nconst warnings = new Set()\nconst warnOnce = (message: string) => {\n if (warnings.has(message)) return\n // eslint-disable-next-line no-console\n console.warn(message)\n warnings.add(message)\n}\n\nconst isExcludedPseudoElement = (selector: string, pseudoState: string) =>\n EXCLUDED_PSEUDO_ELEMENTS.some((element) => selector.endsWith(`${element}:${pseudoState}`))\n\nconst rewriteRule = ({ cssText, selectorText }: CSSStyleRule, shadowRoot?: ShadowRoot) => {\n return cssText.replace(\n selectorText,\n splitSelectors(selectorText)\n .flatMap((selector) => {\n if (selector.includes(\".pseudo-\")) {\n return []\n }\n if (!matchOne.test(selector)) {\n return [selector]\n }\n\n const states: string[] = []\n let plainSelector = selector.replace(matchAll, (_, state) => {\n states.push(state)\n return \"\"\n })\n const classSelector = states.reduce((acc, state) => {\n if (isExcludedPseudoElement(selector, state)) return \"\"\n return acc.replace(new RegExp(`:${state}`, \"g\"), `.pseudo-${state}`)\n }, selector)\n\n let ancestorSelector = \"\"\n const statesAllClassSelectors = states.map((s) => `.pseudo-${s}-all`).join(\"\")\n \n if (selector.startsWith(\":host(\")) {\n const matches = selector.match(/^:host\\(([^ ]+)\\) /)\n if (matches && !matchOne.test(matches[1])) {\n // If :host() did not contain states, then simple replacement won't work.\n ancestorSelector = `:host(${matches[1]}${statesAllClassSelectors}) ${plainSelector.replace(matches[0], \"\")}`\n } else {\n ancestorSelector = states.reduce((acc, state) => {\n if (isExcludedPseudoElement(selector, state)) return \"\"\n return acc.replace(new RegExp(`:${state}`, \"g\"), `.pseudo-${state}-all`)\n }, selector)\n }\n } else if (selector.startsWith(\"::slotted(\") || shadowRoot) {\n if (plainSelector.startsWith(\"::slotted()\")) {\n plainSelector = plainSelector.replace(\"::slotted()\", \"::slotted(*)\")\n }\n ancestorSelector = `:host(${statesAllClassSelectors}) ${plainSelector}`\n } else {\n ancestorSelector = `${statesAllClassSelectors} ${plainSelector}`\n }\n\n return [selector, classSelector, ancestorSelector].filter(\n (selector) => selector && !selector.includes(\":not()\") && !selector.includes(\":has()\")\n )\n })\n .join(\", \")\n )\n}\n\n// Rewrites the style sheet to add alternative selectors for any rule that targets a pseudo state.\n// A sheet can only be rewritten once, and may carry over between stories.\nexport const rewriteStyleSheet = (\n sheet: CSSStyleSheet,\n shadowRoot?: ShadowRoot\n): boolean => {\n try {\n const maximumRulesToRewrite = 1000\n const count = rewriteRuleContainer(sheet, maximumRulesToRewrite, shadowRoot);\n \n if (count >= maximumRulesToRewrite) {\n warnOnce(\"Reached maximum of 1000 pseudo selectors per sheet, skipping the rest.\")\n }\n\n return count > 0\n } catch (e) {\n if (String(e).includes(\"cssRules\")) {\n warnOnce(`Can't access cssRules, likely due to CORS restrictions: ${sheet.href}`)\n } else {\n // eslint-disable-next-line no-console\n console.error(e, sheet.href)\n }\n return false\n }\n}\n\nconst rewriteRuleContainer = (\n ruleContainer: CSSStyleSheet | CSSGroupingRule,\n rewriteLimit: number,\n shadowRoot?: ShadowRoot\n): number => {\n let count = 0\n let index = -1\n for (const cssRule of ruleContainer.cssRules) {\n index++\n let numRewritten = 0\n\n // @ts-expect-error\n if (cssRule.__processed) {\n // @ts-expect-error\n numRewritten = cssRule.__pseudoStatesRewrittenCount\n } else {\n if (\"cssRules\" in cssRule && (cssRule.cssRules as CSSRuleList).length) {\n numRewritten = rewriteRuleContainer(cssRule as CSSGroupingRule, rewriteLimit - count, shadowRoot)\n } else {\n if (!(\"selectorText\" in cssRule)) continue\n const styleRule = cssRule as CSSStyleRule\n if (matchOne.test(styleRule.selectorText)) {\n const newRule = rewriteRule(styleRule, shadowRoot)\n ruleContainer.deleteRule(index)\n ruleContainer.insertRule(newRule, index)\n numRewritten = 1\n }\n }\n // @ts-expect-error\n cssRule.__processed = true\n // @ts-expect-error\n cssRule.__pseudoStatesRewrittenCount = numRewritten\n }\n count += numRewritten\n\n if (count >= rewriteLimit) {\n break\n }\n }\n\n return count\n}\n","import { PARAM_KEY } from \"./constants\"\nimport { withPseudoState } from \"./preview/withPseudoState\"\n\nexport const decorators = [withPseudoState]\nexport const globals = { [PARAM_KEY]: false }\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/preview/withPseudoState.ts","../src/preview/splitSelectors.ts","../src/preview/rewriteStyleSheet.ts","../src/preview.ts"],"names":["ADDON_ID","TOOL_ID","PARAM_KEY","EXCLUDED_PSEUDO_ELEMENT_PATTERNS","PSEUDO_STATES","DOCS_RENDERED","FORCE_REMOUNT","FORCE_RE_RENDER","GLOBALS_UPDATED","STORY_CHANGED","STORY_RENDERED","UPDATE_GLOBALS","addons","useEffect","useMemo","isAtRule","selector","splitSelectors","selectors","result","parentheses","brackets","i","len","char","pseudoStates","pseudoStatesPattern","matchOne","matchAll","warnings","warnOnce","message","replacePseudoStates","allClass","negativeLookbehind","acc","state","replacePseudoStatesWithAncestorSelector","forShadowDOM","additionalHostSelectors","states","withoutPseudoStates","extractPseudoStates","s","_","rewriteNotSelectors","match","originalNot","selectorList","rewrittenNot","rewriteNotSelector","negatedSelectorList","rewrittenSelectors","negatedSelector","rewriteRule","cssText","selectorText","replacementSelectors","classSelector","ancestorSelector","matches","hostInnerSelector","descendantSelector","withNotsReplaced","rewriteStyleSheet","sheet","count","rewriteRuleContainer","e","ruleContainer","rewriteLimit","index","cssRule","numRewritten","styleRule","newRule","channel","shadowHosts","applyClasses","element","classnames","classname","querySelectorPiercingShadowDOM","root","results","el","applyParameter","rootElement","parameter","map","add","target","value","sel","key","keyWithoutAll","updateShadowHost","shadowHost","node","pseudoConfig","rootSelector","pseudoStateConfig","equals","a","b","withPseudoState","StoryFn","viewMode","parameters","id","globalsArgs","globals","config","timeout","rewriteStyleSheets","shadowRoot","styleSheets","init","decorators"],"mappings":"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","sourcesContent":["export const ADDON_ID = \"storybook/pseudo-states\"\nexport const TOOL_ID = `${ADDON_ID}/tool`\nexport const PARAM_KEY = \"pseudo\"\n\n// Regex patterns for pseudo-elements which are not allowed to have classes applied on them\n// E.g. ::-webkit-scrollbar-thumb.pseudo-hover is not a valid selector\nexport const EXCLUDED_PSEUDO_ELEMENT_PATTERNS = [\"::-webkit-scrollbar-thumb\", \"::-webkit-slider-thumb\", \"::part\\\\([^)]+\\\\)\"]\n\n// Dynamic pseudo-classes\n// @see https://www.w3.org/TR/2018/REC-selectors-3-20181106/#dynamic-pseudos\nexport const PSEUDO_STATES = {\n hover: \"hover\",\n active: \"active\",\n focusVisible: \"focus-visible\",\n focusWithin: \"focus-within\",\n focus: \"focus\", // must come after its alternatives\n visited: \"visited\",\n link: \"link\",\n target: \"target\",\n} as const\n\nexport type PseudoState = keyof typeof PSEUDO_STATES\n","/* eslint-env browser */\nimport {\n DOCS_RENDERED,\n FORCE_REMOUNT,\n FORCE_RE_RENDER,\n GLOBALS_UPDATED,\n STORY_CHANGED,\n STORY_RENDERED,\n UPDATE_GLOBALS,\n} from \"@storybook/core-events\"\nimport { DecoratorFunction } from \"@storybook/types\"\nimport { addons, useEffect, useMemo } from \"@storybook/preview-api\"\n\nimport { PSEUDO_STATES, PseudoState } from \"../constants\"\nimport { rewriteStyleSheet } from \"./rewriteStyleSheet\"\n\ntype PseudoStateConfig = {\n [P in PseudoState]?: boolean | string | string[]\n}\n\nexport interface PseudoParameter extends PseudoStateConfig {\n rootSelector?: string\n}\n\nconst channel = addons.getChannel()\nconst shadowHosts = new Set<Element>()\n\n// Drops any existing pseudo state classnames that carried over from a previously viewed story\n// before adding the new classnames. We use forEach for IE compatibility.\nconst applyClasses = (element: Element, classnames: Set<string>) => {\n Object.values(PSEUDO_STATES).forEach((state) => {\n element.classList.remove(`pseudo-${state}`)\n element.classList.remove(`pseudo-${state}-all`)\n })\n classnames.forEach((classname) => element.classList.add(classname))\n}\n\nfunction querySelectorPiercingShadowDOM(root: Element | ShadowRoot, selector: string) {\n const results: Element[] = [];\n root.querySelectorAll('*').forEach((el) => {\n if (el.shadowRoot) {\n results.push(...querySelectorPiercingShadowDOM(el.shadowRoot, selector))\n }\n })\n results.push(...root.querySelectorAll(selector).values())\n return results\n}\n\nconst applyParameter = (rootElement: Element, parameter: PseudoStateConfig = {}) => {\n const map = new Map([[rootElement, new Set<PseudoState>()]])\n const add = (target: Element, state: PseudoState) =>\n map.set(target, new Set([...(map.get(target) || []), state]))\n\n ;(Object.entries(parameter || {}) as [PseudoState, any]).forEach(([state, value]) => {\n if (typeof value === \"boolean\") {\n // default API - applying pseudo class to root element.\n if (value) add(rootElement, `${state}-all` as PseudoState)\n } else if (typeof value === \"string\") {\n // explicit selectors API - applying pseudo class to a specific element\n querySelectorPiercingShadowDOM(rootElement, value).forEach((el) => add(el, state))\n } else if (Array.isArray(value)) {\n // explicit selectors API - we have an array (of strings) recursively handle each one\n value.forEach((sel) => querySelectorPiercingShadowDOM(rootElement, sel).forEach((el) => add(el, state)))\n }\n })\n\n map.forEach((states, target) => {\n const classnames = new Set<string>()\n states.forEach((key) => {\n const keyWithoutAll = key.replace(\"-all\", \"\") as PseudoState\n if (PSEUDO_STATES[key]) {\n classnames.add(`pseudo-${PSEUDO_STATES[key]}`)\n } else if (PSEUDO_STATES[keyWithoutAll]) {\n classnames.add(`pseudo-${PSEUDO_STATES[keyWithoutAll]}-all`)\n }\n })\n applyClasses(target, classnames)\n })\n}\n\n// Traverses ancestry to collect relevant pseudo classnames, and applies them to the shadow host.\n// Shadow DOM can only access classes on its host. Traversing is needed to mimic the CSS cascade.\nconst updateShadowHost = (shadowHost: Element) => {\n const classnames = new Set<string>()\n // Keep any existing \"pseudo-*\" classes (but not \"pseudo-*-all\").\n // \"pseudo-*-all\" classes may be stale and will be re-added as needed.\n shadowHost.className\n .split(\" \")\n .filter((classname) => classname.match(/^pseudo-(.(?!-all))+$/))\n .forEach((classname) => classnames.add(classname))\n // Adopt \"pseudo-*-all\" classes from ancestors (across shadow boundaries)\n for (let node = shadowHost.parentNode; node;) {\n if (node instanceof ShadowRoot) {\n node = node.host\n continue\n }\n if (node instanceof Element) {\n const element = node\n if (element.className) {\n element.className\n .split(\" \")\n .filter((classname) => classname.match(/^pseudo-.+-all$/) !== null)\n .forEach((classname) => classnames.add(classname))\n }\n }\n node = node.parentNode\n }\n applyClasses(shadowHost, classnames)\n}\n\n// Drops the rootSelector from the parameter object, as it is not a pseudo state.\nconst pseudoConfig = (parameter: PseudoParameter) => {\n const { rootSelector, ...pseudoStateConfig } = parameter || {}\n return pseudoStateConfig\n}\n\n// Compares two pseudo state configs to see if they are equal.\n// Uses JSON.stringify to handle arrays, so the order of selectors in the array matters.\nconst equals = (a: PseudoStateConfig = {}, b: PseudoStateConfig = {}) =>\n a !== null &&\n b !== null &&\n Object.keys(a).length === Object.keys(b).length &&\n (Object.keys(a) as PseudoState[]).every(\n (key) => JSON.stringify(a[key]) === JSON.stringify(b[key])\n )\n\n// Global decorator that rewrites stylesheets and applies classnames to render pseudo styles\nexport const withPseudoState: DecoratorFunction = (\n StoryFn,\n { viewMode, parameters, id, globals: globalsArgs }\n) => {\n const { pseudo: parameter } = parameters\n const { pseudo: globals } = globalsArgs\n const { rootSelector } = parameter || {}\n\n const rootElement = useMemo(() => {\n if (rootSelector) {\n return document.querySelector(rootSelector)\n }\n if (viewMode === \"docs\") {\n return document.getElementById(`story--${id}`)\n }\n return (\n document.getElementById(\"storybook-root\") || // Storybook 7.0+\n document.getElementById(\"root\")\n )\n }, [rootSelector, viewMode, id])\n\n // Sync parameter to globals, used by the toolbar (only in canvas as this\n // doesn't make sense for docs because many stories are displayed at once)\n useEffect(() => {\n const config = pseudoConfig(parameter)\n if (viewMode === \"story\" && !equals(config, globals)) {\n channel.emit(UPDATE_GLOBALS, {\n globals: { pseudo: config },\n })\n }\n }, [parameter, viewMode])\n\n // Convert selected states to classnames and apply them to the story root element.\n // Then update each shadow host to redetermine its own pseudo classnames.\n useEffect(() => {\n if (!rootElement) return\n const timeout = setTimeout(() => {\n applyParameter(rootElement, globals || pseudoConfig(parameter))\n shadowHosts.forEach(updateShadowHost)\n }, 0)\n return () => clearTimeout(timeout)\n }, [rootElement, globals, parameter])\n\n return StoryFn()\n}\n\n// Rewrite CSS rules for pseudo-states on all stylesheets to add an alternative selector\nconst rewriteStyleSheets = (shadowRoot?: ShadowRoot) => {\n let styleSheets = Array.from(shadowRoot ? shadowRoot.styleSheets : document.styleSheets)\n if (shadowRoot?.adoptedStyleSheets?.length) styleSheets = shadowRoot.adoptedStyleSheets\n styleSheets.forEach((sheet) => rewriteStyleSheet(sheet, !!shadowRoot))\n if (shadowRoot && shadowHosts) shadowHosts.add(shadowRoot.host)\n}\n\n// Only track shadow hosts for the current story\nchannel.on(STORY_CHANGED, () => shadowHosts.clear())\n\n// Reinitialize CSS enhancements every time the story changes\nchannel.on(STORY_RENDERED, () => rewriteStyleSheets())\nchannel.on(GLOBALS_UPDATED, () => rewriteStyleSheets())\nchannel.on(FORCE_RE_RENDER, () => rewriteStyleSheets())\nchannel.on(FORCE_REMOUNT, () => rewriteStyleSheets())\n\n// Reinitialize CSS enhancements every time a docs page is rendered\nchannel.on(DOCS_RENDERED, () => rewriteStyleSheets())\n\n// IE doesn't support shadow DOM\nif (Element.prototype.attachShadow) {\n // Monkeypatch the attachShadow method so we can handle pseudo styles inside shadow DOM\n // @ts-expect-error (Monkeypatch)\n Element.prototype._attachShadow = Element.prototype.attachShadow\n Element.prototype.attachShadow = function attachShadow(init) {\n // Force \"open\" mode, so we can access the shadowRoot\n // @ts-expect-error (Monkeypatch)\n const shadowRoot = this._attachShadow({ ...init, mode: \"open\" })\n // Wait for it to render and apply its styles before rewriting them\n requestAnimationFrame(() => {\n rewriteStyleSheets(shadowRoot)\n if (shadowHosts.has(shadowRoot.host)) updateShadowHost(shadowRoot.host)\n })\n return shadowRoot\n }\n}\n","const isAtRule = (selector: string) => selector.indexOf(\"@\") === 0\n\nexport const splitSelectors = (selectors: string) => {\n if (isAtRule(selectors)) return [selectors]\n\n let result = []\n let parentheses = 0\n let brackets = 0\n let selector = \"\"\n\n for (let i = 0, len = selectors.length; i < len; i++) {\n const char = selectors[i]\n if (char === \"(\") {\n parentheses += 1\n } else if (char === \")\") {\n parentheses -= 1\n } else if (char === \"[\") {\n brackets += 1\n } else if (char === \"]\") {\n brackets -= 1\n } else if (char === \",\") {\n if (!parentheses && !brackets) {\n result.push(selector.trim())\n selector = \"\"\n continue\n }\n }\n selector += char\n }\n\n result.push(selector.trim())\n return result\n}\n","import { PSEUDO_STATES, EXCLUDED_PSEUDO_ELEMENT_PATTERNS } from \"../constants\"\nimport { splitSelectors } from \"./splitSelectors\"\n\nconst pseudoStates = Object.values(PSEUDO_STATES)\nconst pseudoStatesPattern = `:(${pseudoStates.join(\"|\")})`\nconst matchOne = new RegExp(pseudoStatesPattern)\nconst matchAll = new RegExp(pseudoStatesPattern, \"g\")\n \nconst warnings = new Set()\nconst warnOnce = (message: string) => {\n if (warnings.has(message)) return\n // eslint-disable-next-line no-console\n console.warn(message)\n warnings.add(message)\n}\n\nconst replacePseudoStates = (selector: string, allClass?: boolean) => {\n const negativeLookbehind = `(?<!(?:${EXCLUDED_PSEUDO_ELEMENT_PATTERNS.join(\"|\")})\\\\S*)`\n return pseudoStates.reduce((acc, state) => acc.replace(\n new RegExp(`${negativeLookbehind}:${state}`, \"g\"), \n `.pseudo-${state}${allClass ? \"-all\" : \"\"}`\n ), selector)\n}\n\n// Does not handle :host() or :not() containing pseudo-states. Need to call replaceNotSelectors on the input first.\nconst replacePseudoStatesWithAncestorSelector = (selector: string, forShadowDOM: boolean, additionalHostSelectors?: string) => {\n let { states, withoutPseudoStates } = extractPseudoStates(selector)\n if (states.length === 0 && !additionalHostSelectors) {\n return selector\n }\n const selectors = `${additionalHostSelectors ?? \"\"}${states.map((s) => `.pseudo-${s}-all`).join(\"\")}`\n\n // If there was a :host-context() containing only pseudo-states, we will later add a :host selector that replaces it.\n withoutPseudoStates = withoutPseudoStates.replace(\":host-context(*)\", \"\").trimStart()\n\n // If there is a :host-context() selector, we don't need to introduce a :host() selector.\n // We can just append the pseudo-state classes to the :host-context() selector.\n return withoutPseudoStates.startsWith(\":host-context(\")\n ? withoutPseudoStates.replace(/(?<=:host-context\\(\\S+)\\)/, `)${selectors}`)\n : forShadowDOM\n ? `:host(${selectors}) ${withoutPseudoStates}`\n : `${selectors} ${withoutPseudoStates}`\n}\n\nconst extractPseudoStates = (selector: string) => {\n const states = new Set()\n const withoutPseudoStates = selector\n .replace(matchAll, (_, state) => {\n states.add(state)\n return \"\"\n })\n // If removing pseudo-state selectors from inside a functional selector left it empty (thus invalid), must fix it by adding '*'.\n .replaceAll(\"()\", \"(*)\")\n // If a selector list was left with blank items (e.g. \", foo, , bar, \"), remove the extra commas/spaces.\n .replace(/(?<=[\\s(]),\\s+|(,\\s+)+(?=\\))/g, \"\") || \"*\"\n\n return {\n states: Array.from(states),\n withoutPseudoStates\n }\n}\n\nconst rewriteNotSelectors = (selector: string, forShadowDOM: boolean) => {\n return [...selector.matchAll(/:not\\(([^)]+)\\)/g)].reduce((acc, match) => {\n const originalNot = match[0]\n const selectorList = match[1]\n const rewrittenNot = rewriteNotSelector(selectorList, forShadowDOM)\n return acc.replace(originalNot, rewrittenNot)\n }, selector)\n}\n\nconst rewriteNotSelector = (negatedSelectorList: string, forShadowDOM: boolean) => {\n const rewrittenSelectors: string[] = []\n // For each negated selector\n for (const negatedSelector of negatedSelectorList.split(/,\\s*/)) {\n // :not cannot be nested and cannot contain pseudo-elements, so no need to worry about that.\n // Also, there's no compelling use case for :host() inside :not(), so we don't handle that.\n rewrittenSelectors.push(replacePseudoStatesWithAncestorSelector(negatedSelector, forShadowDOM))\n }\n return `:not(${rewrittenSelectors.join(\", \")})`\n}\n\nconst rewriteRule = ({ cssText, selectorText }: CSSStyleRule, forShadowDOM: boolean) => {\n return cssText.replace(\n selectorText,\n splitSelectors(selectorText)\n .flatMap((selector) => {\n if (selector.includes(\".pseudo-\")) {\n return []\n }\n const replacementSelectors = [selector]\n if (!matchOne.test(selector)) {\n return replacementSelectors\n }\n\n const classSelector = replacePseudoStates(selector)\n if (classSelector !== selector) {\n replacementSelectors.push(classSelector)\n }\n\n let ancestorSelector = \"\"\n \n if (selector.startsWith(\":host(\")) {\n const matches = selector.match(/^:host\\((\\S+)\\)\\s+(.+)$/)\n if (matches && matchOne.test(matches[2])) {\n // Simple replacement won't work on pseudo-state selectors outside of :host().\n // E.g. :host(.foo) .bar:hover -> :host(.foo.pseudo-hover-all) .bar\n // E.g. :host(.foo:focus) .bar:hover -> :host(.foo.pseudo-focus-all.pseudo-hover-all) .bar\n let hostInnerSelector = matches[1]\n let descendantSelector = matches[2]\n // Simple replacement is fine for pseudo-state selectors inside :host() (even if inside :not()).\n hostInnerSelector = replacePseudoStates(hostInnerSelector, true)\n // Rewrite any :not selectors in the descendant selector.\n descendantSelector = rewriteNotSelectors(descendantSelector, true)\n // Any remaining pseudo-states in the descendant selector need to be moved into the host selector.\n ancestorSelector = replacePseudoStatesWithAncestorSelector(descendantSelector, true, hostInnerSelector)\n } else {\n // Don't need to specially handle :not() because:\n // - if inside :host(), simple replacement is sufficient\n // - if outside :host(), didn't match any pseudo-states\n ancestorSelector = replacePseudoStates(selector, true)\n }\n } else {\n const withNotsReplaced = rewriteNotSelectors(selector, forShadowDOM)\n ancestorSelector = replacePseudoStatesWithAncestorSelector(withNotsReplaced, forShadowDOM)\n }\n replacementSelectors.push(ancestorSelector)\n\n return replacementSelectors\n })\n .join(\", \")\n )\n}\n\n// Rewrites the style sheet to add alternative selectors for any rule that targets a pseudo state.\n// A sheet can only be rewritten once, and may carry over between stories.\nexport const rewriteStyleSheet = (\n sheet: CSSStyleSheet,\n forShadowDOM = false\n): boolean => {\n try {\n const maximumRulesToRewrite = 1000\n const count = rewriteRuleContainer(sheet, maximumRulesToRewrite, forShadowDOM);\n \n if (count >= maximumRulesToRewrite) {\n warnOnce(\"Reached maximum of 1000 pseudo selectors per sheet, skipping the rest.\")\n }\n\n return count > 0\n } catch (e) {\n if (String(e).includes(\"cssRules\")) {\n warnOnce(`Can't access cssRules, likely due to CORS restrictions: ${sheet.href}`)\n } else {\n // eslint-disable-next-line no-console\n console.error(e, sheet.href)\n }\n return false\n }\n}\n\nconst rewriteRuleContainer = (\n ruleContainer: CSSStyleSheet | CSSGroupingRule,\n rewriteLimit: number,\n forShadowDOM: boolean\n): number => {\n let count = 0\n let index = -1\n for (const cssRule of ruleContainer.cssRules) {\n index++\n let numRewritten = 0\n\n // @ts-expect-error\n if (cssRule.__processed) {\n // @ts-expect-error\n numRewritten = cssRule.__pseudoStatesRewrittenCount\n } else {\n if (\"cssRules\" in cssRule && (cssRule.cssRules as CSSRuleList).length) {\n numRewritten = rewriteRuleContainer(cssRule as CSSGroupingRule, rewriteLimit - count, forShadowDOM)\n } else {\n if (!(\"selectorText\" in cssRule)) continue\n const styleRule = cssRule as CSSStyleRule\n if (matchOne.test(styleRule.selectorText)) {\n const newRule = rewriteRule(styleRule, forShadowDOM)\n ruleContainer.deleteRule(index)\n ruleContainer.insertRule(newRule, index)\n numRewritten = 1\n }\n }\n // @ts-expect-error\n cssRule.__processed = true\n // @ts-expect-error\n cssRule.__pseudoStatesRewrittenCount = numRewritten\n }\n count += numRewritten\n\n if (count >= rewriteLimit) {\n break\n }\n }\n\n return count\n}\n","import { PARAM_KEY } from \"./constants\"\nimport { withPseudoState } from \"./preview/withPseudoState\"\n\nexport const decorators = [withPseudoState]\nexport const globals = { [PARAM_KEY]: false }\n"]}
|