@phun-ky/speccer 9.0.13 → 9.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/README.md +33 -1
- package/dist/speccer.css +115 -0
- package/dist/speccer.esm.js +1 -1
- package/dist/speccer.esm.js.map +1 -1
- package/dist/speccer.js +1 -1
- package/dist/speccer.js.map +1 -1
- package/dist/speccer.min.css +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
- [Curly brackets](#curly-brackets)
|
|
28
28
|
- [Element typography](#element-typography)
|
|
29
29
|
- [Mark elements](#mark-elements)
|
|
30
|
+
- [A11y notation](#a11y-notation)
|
|
31
|
+
- [Tab stops](#tab-stops)
|
|
32
|
+
- [Landmarks and regions](#landmarks-and-regions)
|
|
33
|
+
- [Keys and shortcut](#keys-and-shortcut)
|
|
30
34
|
- [Customization](#customization)
|
|
31
35
|
- [Contributing](#contributing)
|
|
32
36
|
|
|
@@ -313,9 +317,37 @@ In your component examples, use the following attribute.
|
|
|
313
317
|
<div data-speccer-mark …>…</div>
|
|
314
318
|
```
|
|
315
319
|
|
|
320
|
+
### A11y notation
|
|
321
|
+
|
|
322
|
+
With speccer, you can also display accessibility notation, like [Accessibility Bluelines](https://dribbble.com/shots/6269661-Accessibility-Bluelines?utm_source=Clipboard_Shot&utm_campaign=jeremyelder&utm_content=Accessibility%20Bluelines&utm_medium=Social_Share&utm_source=Clipboard_Shot&utm_campaign=jeremyelder&utm_content=Accessibility%20Bluelines&utm_medium=Social_Share):
|
|
323
|
+
|
|
324
|
+
Prior art: [Jeremy Elder](https://twitter.com/JeremyElder)
|
|
325
|
+
|
|
326
|
+
#### Tab stops
|
|
327
|
+
|
|
328
|
+

|
|
329
|
+
|
|
330
|
+
If you want to display tab stops, append `data-speccer-a11y-tabstops` as an attribute to the container you want to display the tab stops in.
|
|
331
|
+
|
|
332
|
+
#### Landmarks and regions
|
|
333
|
+
|
|
334
|
+

|
|
335
|
+
|
|
336
|
+
If you want to display landmarks and regions, append `data-speccer-a11y-landmark` as an attribute to the container you want to display the landmarks and regions in.
|
|
337
|
+
|
|
338
|
+
#### Keys and shortcut
|
|
339
|
+
|
|
340
|
+

|
|
341
|
+
|
|
342
|
+
If you want to display the shortcut with keys used for elements, use `data-speccer-a11y-shortcut="<shortcut>"` on the element that uses this shortcut:
|
|
343
|
+
|
|
344
|
+
```html
|
|
345
|
+
<button type="button" data-speccer-a11y-shortcut="ctrl + s">Save</button>
|
|
346
|
+
```
|
|
347
|
+
|
|
316
348
|
## Customization
|
|
317
349
|
|
|
318
|
-

|
|
319
351
|
|
|
320
352
|
Allthough the styling works nicely with dark mode, you can use the provided CSS variables to customize the look and feel. If more control is needed, you can use CSS overrides :)
|
|
321
353
|
|
package/dist/speccer.css
CHANGED
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
--ph-speccer-line-width: 1px;
|
|
25
25
|
--ph-speccer-line-width-negative: -1px;
|
|
26
26
|
--ph-speccer-measure-size: 8px;
|
|
27
|
+
--ph-speccer-a11y-color-background: #1868b2;
|
|
28
|
+
--ph-speccer-a11y-landmark-color-background: #7e60c5;
|
|
27
29
|
}
|
|
28
30
|
svg.ph-speccer,
|
|
29
31
|
.ph-speccer.speccer,
|
|
@@ -736,3 +738,116 @@ svg.ph-speccer .ph-speccer.path {
|
|
|
736
738
|
border-style: solid;
|
|
737
739
|
position: absolute;
|
|
738
740
|
}
|
|
741
|
+
[data-speccer-a11y] {
|
|
742
|
+
counter-reset: speccer-a11y-tabstops;
|
|
743
|
+
}
|
|
744
|
+
.ph-speccer.speccer.a11y.tabstops {
|
|
745
|
+
position: absolute;
|
|
746
|
+
height: 48px;
|
|
747
|
+
width: 48px;
|
|
748
|
+
background-color: var(--ph-speccer-a11y-color-background);
|
|
749
|
+
border-radius: 0.5rem;
|
|
750
|
+
color: var(--ph-speccer-color-text-light);
|
|
751
|
+
font-family: var(--ph-speccer-font-family);
|
|
752
|
+
counter-increment: speccer-a11y-tabstops;
|
|
753
|
+
border: 3px solid var(--ph-speccer-a11y-color-background);
|
|
754
|
+
}
|
|
755
|
+
.ph-speccer.speccer.a11y.tabstops::before {
|
|
756
|
+
position: absolute;
|
|
757
|
+
top: calc(0.5rem - 2px);
|
|
758
|
+
left: calc(0.5rem - 2px);
|
|
759
|
+
content: counter(speccer-a11y-tabstops);
|
|
760
|
+
font-size: 12px;
|
|
761
|
+
text-align: left;
|
|
762
|
+
}
|
|
763
|
+
.ph-speccer.speccer.a11y.tabstops::after {
|
|
764
|
+
display: flex;
|
|
765
|
+
justify-content: flex-end;
|
|
766
|
+
align-items: flex-end;
|
|
767
|
+
position: absolute;
|
|
768
|
+
left: 0.5rem;
|
|
769
|
+
right: 0.5rem;
|
|
770
|
+
bottom: 0.5rem;
|
|
771
|
+
height: 2rem;
|
|
772
|
+
content: "⇥";
|
|
773
|
+
font-size: 2rem;
|
|
774
|
+
color: var(--ph-speccer-color-text-light);
|
|
775
|
+
font-family: var(--ph-speccer-font-family);
|
|
776
|
+
}
|
|
777
|
+
.ph-speccer.speccer.a11y.landmark {
|
|
778
|
+
position: absolute;
|
|
779
|
+
height: 48px;
|
|
780
|
+
width: 48px;
|
|
781
|
+
background-color: var(--ph-speccer-a11y-landmark-color-background);
|
|
782
|
+
border-radius: 0.5rem;
|
|
783
|
+
color: var(--ph-speccer-color-text-light);
|
|
784
|
+
font-family: var(--ph-speccer-font-family);
|
|
785
|
+
border: 3px solid var(--ph-speccer-a11y-landmark-color-background);
|
|
786
|
+
box-shadow: inset 0 0 0 2px var(--ph-speccer-color-text-light);
|
|
787
|
+
justify-content: center;
|
|
788
|
+
font-size: 1rem;
|
|
789
|
+
line-height: 100%;
|
|
790
|
+
align-items: center;
|
|
791
|
+
padding: 0.5rem;
|
|
792
|
+
pointer-events: auto;
|
|
793
|
+
}
|
|
794
|
+
.ph-speccer.speccer.a11y.landmark::after {
|
|
795
|
+
top: 100%;
|
|
796
|
+
left: 50%;
|
|
797
|
+
border: solid transparent;
|
|
798
|
+
content: "";
|
|
799
|
+
height: 0;
|
|
800
|
+
width: 0;
|
|
801
|
+
position: absolute;
|
|
802
|
+
pointer-events: none;
|
|
803
|
+
border-color: rgba(126,96,197,0);
|
|
804
|
+
border-top-color: var(--ph-speccer-a11y-landmark-color-background);
|
|
805
|
+
border-width: 12px;
|
|
806
|
+
margin-left: -12px;
|
|
807
|
+
}
|
|
808
|
+
.ph-speccer.speccer.a11y.region {
|
|
809
|
+
position: absolute;
|
|
810
|
+
outline: 2px solid var(--ph-speccer-a11y-landmark-color-background);
|
|
811
|
+
outline-offset: 2px;
|
|
812
|
+
}
|
|
813
|
+
.ph-speccer.speccer.a11y.shortcut-holder {
|
|
814
|
+
position: absolute;
|
|
815
|
+
height: 48px;
|
|
816
|
+
min-width: 120px;
|
|
817
|
+
display: flex;
|
|
818
|
+
flex-direction: row;
|
|
819
|
+
justify-content: flex-start;
|
|
820
|
+
align-items: center;
|
|
821
|
+
grid-gap: 0.5rem;
|
|
822
|
+
}
|
|
823
|
+
.ph-speccer.speccer.a11y.shortcut-holder kbd.ph-speccer.speccer.a11y.shortcut {
|
|
824
|
+
flex-shrink: 0;
|
|
825
|
+
position: relative;
|
|
826
|
+
background-color: var(--ph-speccer-a11y-color-background);
|
|
827
|
+
border-radius: 0.5rem;
|
|
828
|
+
color: var(--ph-speccer-color-text-light);
|
|
829
|
+
font-family: var(--ph-speccer-font-family);
|
|
830
|
+
display: inline-flex;
|
|
831
|
+
text-transform: uppercase;
|
|
832
|
+
height: 48px;
|
|
833
|
+
border: 3px solid var(--ph-speccer-a11y-color-background);
|
|
834
|
+
min-width: 48px;
|
|
835
|
+
font-size: 1.5rem;
|
|
836
|
+
justify-content: center;
|
|
837
|
+
align-items: center;
|
|
838
|
+
}
|
|
839
|
+
.ph-speccer.speccer.a11y.shortcut-holder kbd.ph-speccer.speccer.a11y.shortcut.modifier {
|
|
840
|
+
justify-content: flex-start;
|
|
841
|
+
align-items: flex-end;
|
|
842
|
+
padding: 0.25rem;
|
|
843
|
+
font-size: 1rem;
|
|
844
|
+
width: 80px;
|
|
845
|
+
text-transform: lowercase;
|
|
846
|
+
}
|
|
847
|
+
.ph-speccer.speccer.a11y.shortcut-holder kbd.ph-speccer.speccer.a11y.shortcut.physical {
|
|
848
|
+
justify-content: flex-start;
|
|
849
|
+
align-items: flex-end;
|
|
850
|
+
padding: 0.25rem;
|
|
851
|
+
font-size: 1rem;
|
|
852
|
+
text-transform: lowercase;
|
|
853
|
+
}
|
package/dist/speccer.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var t,e,o;!function(t){t.Empty="",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(t||(t={})),function(t){t.Outline="outline",t.Enclose="enclose",t.Full="full",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top",t.SVG="svg",t.Curly="curly"}(e||(e={})),function(t){t.Width="width",t.Height="height",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(o||(o={}));const i=t=>t.split(" "),n=t=>i(t).includes(e.Right),r=t=>i(t).includes(e.Bottom),s=t=>i(t).includes(e.Full),a=t=>i(t).includes(e.Enclose),p=t=>t.includes(e.Curly)&&t.includes(e.Full),c=t=>"string"==typeof t,l=t=>!c(t),h=t=>"number"==typeof t,d=t=>!h(t),f=t=>void 0===t,m=()=>new Promise(requestAnimationFrame),u=t=>t.top,g=t=>t.left+t.width,y=t=>t.top+t.height,w=t=>t.left,x=t=>t.left+t.width/2,b=t=>t.top+t.height/2,E={center:t=>({x:x(t),y:b(t)}),top:t=>({x:x(t),y:u(t)}),right:t=>({x:g(t),y:b(t)}),bottom:t=>({x:x(t),y:y(t)}),left:t=>({x:w(t),y:b(t)}),"right-top":t=>({x:g(t),y:u(t)}),"right-bottom":t=>({x:g(t),y:y(t)}),"left-top":t=>({x:w(t),y:u(t)}),"left-bottom":t=>({x:w(t),y:y(t)}),"top-left":t=>({x:w(t),y:u(t)}),"top-right":t=>({x:g(t),y:u(t)}),"bottom-left":t=>({x:w(t),y:y(t)}),"bottom-right":t=>({x:g(t),y:y(t)}),"top-center":t=>({x:x(t),y:u(t)}),"right-center":t=>({x:g(t),y:b(t)}),"bottom-center":t=>({x:x(t),y:y(t)}),"left-center":t=>({x:w(t),y:b(t)})},$=async(t,e="center")=>{if(!e)throw Error("No position given");if(l(e))throw Error("The position given is not the required type: pos: "+typeof e);const o=["center","left","right","top","bottom","right-top","right-bottom","left-top","left-bottom","top-left","top-right","bottom-left","bottom-right","top-center","right-center","bottom-center","left-center"];if(!o.includes(e))throw Error(`The position given does not match allowed positions to use! Valid positions are: ${o.join(", ")}`);await m();const i=t.getBoundingClientRect();return E[e](i)},A=async(t,e,o="center",i="center")=>{if(!t||!e)throw Error("No element given");const{x:n,y:r}=await $(t,o),{x:s,y:a}=await $(e,i);return{x1:n,y1:r,x2:s,y2:a}},v=(t,e)=>{const{x1:o,x2:i,y1:n,y2:r}=t,{direct:s=!1,firstSet:a=!1,direction:p}=e;let c={x:o+(i-o)/2,y:n},l={x:o+(i-o)/2,y:r};return s&&(a?"west"===p?(c={x:o-32,y:n-8},l={x:i+32,y:r}):"south"===p?(c={x:o-8,y:n+32},l={x:i,y:r-32}):"east"===p?(c={x:o+32,y:n-8},l={x:i-32,y:r}):(c={x:o-8,y:n-32},l={x:i,y:r+32}):"west"===p?(c={x:o-32,y:n+8},l={x:i+32,y:r}):"south"===p?(c={x:o+8,y:n+32},l={x:i,y:r-32}):"east"===p?(c={x:o+32,y:n+8},l={x:i-32,y:r}):(c={x:o+8,y:n-32},l={x:i,y:r+32})),{firstPoint:{x:o,y:n},firstControl:c,lastPoint:{x:i,y:r},lastControl:l}},S=async(t,e,o)=>{const{pos1:i,pos2:n,firstSet:r=!1,direction:s}=o,{x1:a,y1:p,x2:c,y2:l}=await A(t,e,i,n);let h=0,d=0;"north"===s?d=8:"west"===s?h=8:"east"===s?h=-8:"south"===s&&(d=-8);const{firstPoint:f,firstControl:m,lastControl:u,lastPoint:g}=v({x1:a+0,x2:c+h,y1:p+0+document.documentElement.scrollTop,y2:l+d+document.documentElement.scrollTop},{direct:!0,firstSet:r,direction:s});return`M ${f.x} ${f.y}C ${m.x} ${m.y}, ${u.x} ${u.y}, ${g.x} ${g.y}`},P=async({start:t,stop:e,crude:o=!1})=>{const{x1:i,y1:n,x2:r,y2:s}=await A(t,e),a=((t,e,o,i,n=!0)=>{if(f(t)||f(e)||f(o)||f(i))throw new SyntaxError("Missing input for `angle`");if(d(t)||d(e)||d(o)||d(i))throw TypeError(`Parameters for \`angle\` do not have the required type. Requires number! Got: ${typeof t} ${typeof e} ${typeof o} ${typeof i}`);const r=i-e,s=o-t;let a=Math.atan2(r,s);return a*=180/Math.PI,n&&a<0&&(a+=360),a})(i,n,r,s);return o?(t=>{if(t>360)throw new RangeError("Parameter cannot exceed 360");if(t<0)throw new RangeError("Parameter cannot be lower than 0");return t>=45&&t<=135?"south":t>135&&t<=225?"west":t>225&&t<=315?"north":"east"})(a):(t=>{if(t>360)throw new RangeError("Parameter cannot exceed 360");if(t<0)throw new RangeError("Parameter cannot be lower than 0");return t>=0&&t<=22.5?"east":t>=22.5&&t<=67.5?"south-east":t>=67.5&&t<=112.5?"south":t>=112.5&&t<=157.5?"south-west":t>=157.5&&t<=202.5?"west":t>=202.5&&t<=247.5?"north-west":t>=247.5&&t<=292.5?"north":t>=292.5&&t<=337.5?"north-east":"east"})(a)},C=()=>"_"+Math.random().toString(36).substring(2,11),B=async(t,e)=>{var o;if(!(!t||!e||c(e)||h(e)||(o=e,"boolean"==typeof o)||Array.isArray(e)&&!e.length||!Object.keys(e).length&&e.constructor===Object))if(await m(),Array.isArray(e))for(const o of e)t.style[o.key]=o.value;else for(const o of Object.keys(e))t.style[o]=e[o]},R=async t=>(await m(),getComputedStyle(t,null));class L{#t;#e;startElement;stopElement;firstPathElement;secondPathElement;constructor(t,e){this.#o(t,e)}#o(t,e){if(!t||!e)throw new Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw new Error("stopElement is not in the DOM");if(!document.body.contains(t))throw new Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,this.#t=document.getElementById("ph-speccer-svg"),this.#e=document.getElementById("ph-speccer-path"),!this.#e||!this.#t)throw new Error("Missing required SVG element to draw lines. Please see the documentation");B(this.#t,{height:`${document.body.scrollHeight}px`}),this.connect()}connect(){this.draw(this.#e)}#i(t){if(!t)throw new Error("No path given to #getPathElement!");const e=`ph_draw_path-path-${C()}`,o=t.cloneNode(!1),i=this.startElement.getAttribute("id")||C();return this.startElement.setAttribute("id",i),o.setAttribute("data-start-el",i),o.setAttribute("id",e),o.classList.remove("original"),o.classList.add("speccer"),o}async draw(t){if(!t)throw new Error("No path given to draw!");const e=this.#i(t),o=this.#i(t);if(!t.parentNode)throw new Error("No parentNode found for path");this.firstPathElement=t.parentNode.insertBefore(e,t.nextSibling),this.secondPathElement=t.parentNode.insertBefore(o,t.nextSibling);const i=await P({stop:this.stopElement,start:this.startElement,crude:!0}),{path1pos1:n,path1pos2:r,path2pos1:s,path2pos2:a}=(t=>{let e,o,i,n;switch(t){case"east":e="right-top",o="left-center",i="right-bottom",n="left-center";break;case"south":e="bottom-left",o="top-center",i="bottom-right",n="top-center";break;case"west":e="left-top",o="right-center",i="left-bottom",n="right-center";break;default:e="top-left",o="bottom-center",i="top-right",n="bottom-center"}return{path1pos1:e,path1pos2:o,path2pos1:i,path2pos2:n}})(i),p=await S(this.startElement,this.stopElement,{pos1:n,pos2:r,firstSet:!0,direction:i}),c=await S(this.startElement,this.stopElement,{pos1:s,pos2:a,direction:i});this.firstPathElement.setAttribute("data-direction",i),this.firstPathElement.setAttribute("data-pos1",n),this.firstPathElement.setAttribute("data-pos2",r),this.firstPathElement.setAttribute("d",p),this.secondPathElement.setAttribute("data-direction",i),this.secondPathElement.setAttribute("data-pos1",s),this.secondPathElement.setAttribute("data-pos2",a),this.secondPathElement.setAttribute("d",c)}}window.DrawSVGCurlyBracket=L;class T{#t;#e;startElement;stopElement;line;constructor(t,e){this.#o(t,e)}#o(t,e){if(!t||!e)throw new Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw new Error("stopElement is not in the DOM");if(!document.body.contains(t))throw new Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,this.#t=document.getElementById("ph-speccer-svg"),this.#e=document.getElementById("ph-speccer-path"),!this.#e||!this.#t)throw new Error("Missing required SVG element to draw lines. Please see the documentation");B(this.#t,{height:`${document.body.scrollHeight}px`}),this.connect()}connect(){this.draw(this.#e)}async draw(t){if(!t)throw new Error("No path given to draw!");const e=`ph_draw_path-path-${C()}`,o=t.cloneNode(!1),i=this.startElement.getAttribute("id")||C();if(this.startElement.setAttribute("id",i),o.setAttribute("id",e),o.setAttribute("data-start-el",i),o.classList.remove("original"),o.classList.add("speccer"),!t.parentNode)throw new Error("No parentNode found for path");this.line=t.parentNode.insertBefore(o,t.nextSibling);const n=await P({start:this.startElement,stop:this.stopElement,crude:!0}),{pos1:r,pos2:s}=(t=>{let e,o;switch(t){case"east":e="right",o="left";break;case"south":e="bottom",o="top";break;case"west":e="left",o="right";break;default:e="top",o="bottom"}return{pos1:e,pos2:o}})(n),a=await(async(t,e,o)=>{const{pos1:i,pos2:n}=o,{x1:r,y1:s,x2:a,y2:p}=await A(t,e,i,n),{firstPoint:c,firstControl:l,lastControl:h,lastPoint:d}=v({x1:r,x2:a,y1:s,y2:p},{direction:""});return`M ${c.x} ${c.y}C ${l.x} ${l.y}, ${h.x} ${h.y}, ${d.x} ${d.y}`})(this.startElement,this.stopElement,{pos1:r,pos2:s});this.line.setAttribute("data-direction",n),this.line.setAttribute("data-pos1",r),this.line.setAttribute("data-pos2",s),this.line.setAttribute("d",a)}}window.DrawSVGLine=T;const N=(t,e,o="noop")=>{t&&(!e||e&&!e.length||e.trim().split(" ").filter((t=>t!==o)).forEach((e=>t.classList.add(e))))},I=(t,e)=>t?!e&&l(t)?Object.keys(t).filter((e=>t[e])).join(" ").trim():`${t.trim()} ${e?Object.keys(e).filter((t=>e[t])).join(" "):""}`.trim():"",M=[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ"],O=t=>parseInt(t,10),q=t=>t.includes("Top")?t.replace("Top"," top"):t.includes("Right")?t.replace("Right"," right"):t.includes("Bottom")?t.replace("Bottom"," bottom"):t.includes("Left")?t.replace("Left"," left"):"",H=t=>O(getComputedStyle(t).getPropertyValue("--ph-speccer-pin-space"))||48,k=(t,e,o)=>t-e.width/2+o.width/2,V=(t,e,o)=>t-e.height/2+o.height/2,W=async t=>{await m();const e=t.getBoundingClientRect(),o=e.top+window.scrollY,i=e.left+window.scrollX;return{height:e.height,width:e.width,top:o,left:i}},z=async(t,e)=>{await m();const o=t.getBoundingClientRect(),i=await W(e),n=await(async(t,e)=>{await m();const o=t.getBoundingClientRect(),i=e.getBoundingClientRect(),n=i.top+window.scrollY,r=i.left+window.scrollX;return{height:i.height,width:i.width,top:V(n,o,i),left:k(r,o,i)}})(t,e),r=i.height,s=i.width,a=o.height,p=o.width;return{absolute:()=>({top:i.top,left:i.left,height:r,width:s}),toTop:({center:t=!1,sourceHeight:e=a,modifier:o=0}={})=>({top:i.top+e+o,left:t?n.left:i.left,height:r,width:s}),fromTop:({center:t=!1,sourceHeight:e=a,modifier:o=0}={})=>({top:i.top-e-o,left:t?n.left:i.left,height:r,width:s}),toBottom:({center:t=!1,sourceHeight:e=a,targetHeight:o=r,modifier:p=0}={})=>({top:i.top+o-(e+p),left:t?n.left:i.left,height:r,width:s}),fromBottom:({center:t=!1,targetHeight:e=r,modifier:o=0}={})=>({top:i.top+e+o,left:t?n.left:i.left,height:r,width:s}),toLeft:({center:t=!1,sourceWidth:e=p,modifier:o=0}={})=>({top:t?n.top:i.top,left:i.left+e+o,height:r,width:s}),fromLeft:({center:t=!1,sourceWidth:e=p,modifier:o=0}={})=>({top:t?n.top:i.top,left:i.left-e-o,height:r,width:s}),toRight:({center:t=!1,sourceWidth:e=p,targetWidth:o=s,modifier:a=0}={})=>({top:t?n.top:i.top,left:i.left+o-(e+a),height:r,width:s}),fromRight:({center:t=!1,targetWidth:e=s,modifier:o=0}={})=>({top:t?n.top:i.top,left:i.left+e+o,height:r,width:s})}},j=async(t,o,p,c)=>{await m();const{isCurly:l=!1}=c||{},h=H(p),d=O(getComputedStyle(p).getPropertyValue("--ph-speccer-measure-size"))||8;const f=await z(p,o);if(a(t)){const{left:t,top:e,height:o,width:i}=f.absolute();return{left:`${t}px`,top:`${e}px`,height:`${o}px`,width:`${i}px`}}if(i(t).includes(e.Left)){if(s(t)&&!l){const{left:t,top:e,height:o}=f.fromLeft({sourceWidth:d});return{left:`${t}px`,top:`${e}px`,height:`${o}px`}}const{left:e,top:o}=f.fromLeft({center:!0,modifier:l?h/1.5:h});return{left:`${e}px`,top:`${o}px`}}if(n(t)){if(s(t)&&!l){const{left:t,top:e,height:o}=f.fromRight({center:!1});return{left:`${t}px`,top:`${e}px`,height:`${o}px`}}const{left:e,top:o}=f.fromRight({center:!0,modifier:l?h/1.5:h});return{left:`${e}px`,top:`${o}px`}}if(r(t)){if(s(t)&&!l){const{left:t,top:e,width:o}=f.fromBottom({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${o}px`}}const{left:e,top:o}=f.fromBottom({center:!0,modifier:l?h/1.5:h});return{left:`${e}px`,top:`${o}px`}}if(s(t)&&!l){const{left:t,top:e,width:o}=f.fromTop({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${o}px`}}const{left:u,top:g}=f.fromTop({center:!0,modifier:l?h/1.5:h});return{left:`${u}px`,top:`${g}px`}},F=(t="",e,o="span")=>{const i=document.createElement(o),n=document.createTextNode(t),r={};null!==e&&""!==e&&(r[e]=!0),!s(e)&&!a(e)||s(e)&&p(e)?i.appendChild(n):(s(e)||a(e))&&i.setAttribute("data-dissection-counter",t);const c=I("ph-speccer speccer dissection",r);return N(i,c),i},D=async t=>{if(!t)return;const o=t.querySelectorAll("[data-anatomy]");if(o){let t=0;o.forEach((async(o,i)=>{if(!o)return;const n=o.getAttribute("data-anatomy")||"";if(!n||""===n||!n.includes(e.Outline))return;let r=M[i];r||(r=`${M[t]}${M[t].toLowerCase()}`,t++);const s=F(r,n);document.body.appendChild(s);const a=await j(n,o,s,{isCurly:p(n)});await B(s,a),n.includes(e.SVG)&&!p(n)?new T(o,s):p(n)&&new L(o,s)}))}},G=(t="",e="",o="span")=>{const i=document.createElement(o);return i.setAttribute("title",`${t}px`),i.setAttribute("data-measure",`${parseInt(`${t}`,10)}px`),N(i,`ph-speccer speccer measure ${e}`),i},_=async t=>{if(!t)return;const e=t.getAttribute("data-speccer-measure");if(""===e||!e)return;const s=await R(t);if("none"===s.display||"0"===s.opacity||"hidden"===s.visibility)return;await m();const a=t.getBoundingClientRect();if(i(e).includes(o.Width))if(r(e)){const o=G(a.width,e);document.body.appendChild(o);const i=await z(o,t),{left:n,top:r,width:s}=i.fromBottom({center:!1});await B(o,{left:`${n}px`,top:`${r}px`,width:`${s}px`})}else{const o=G(a.width,e);document.body.appendChild(o);const i=await z(o,t),{left:n,top:r,width:s}=i.fromTop({center:!1,modifier:-8});await B(o,{left:`${n}px`,top:`${r}px`,width:`${s}px`})}else if((t=>i(t).includes(o.Height))(e))if(n(e)){const o=G(a.height,e);document.body.appendChild(o);const i=await z(o,t),{left:n,top:r,height:s}=i.fromRight({center:!1});await B(o,{left:`${n}px`,top:`${r}px`,height:`${s}px`})}else{const o=G(a.height,e);document.body.appendChild(o);const i=await z(o,t),{left:n,top:r,height:s}=i.fromLeft({center:!1,modifier:-8});await B(o,{left:`${n}px`,top:`${r}px`,height:`${s}px`})}},X=async(t,e,o,i)=>{await m();const n=i.getBoundingClientRect(),r=await W(i);"marginTop"===t&&B(o,{height:`${e}px`,width:n.width+"px",left:r.left+"px",top:r.top-e+"px"}),"marginRight"===t&&B(o,{height:n.height+"px",width:`${e}px`,left:r.left+parseInt(n.width+"",10)+"px",top:r.top+"px"}),"marginBottom"===t&&B(o,{height:`${e}px`,width:n.width+"px",left:r.left+"px",top:r.top+parseInt(n.height+"",10)+"px"}),"marginLeft"===t&&B(o,{height:n.height+"px",width:`${e}px`,left:r.left-e+"px",top:r.top+"px"}),"paddingTop"===t&&B(o,{height:`${e}px`,width:n.width+"px",left:r.left+"px",top:r.top+"px"}),"paddingBottom"===t&&B(o,{height:`${e}px`,width:n.width+"px",left:r.left+"px",top:r.top+(parseInt(n.height+"",10)-e)+"px"}),"paddingRight"===t&&B(o,{height:n.height+"px",width:`${e}px`,left:r.left+(parseInt(n.width+"",10)-e)+"px",top:r.top+"px"}),"paddingLeft"===t&&B(o,{height:n.height+"px",width:`${e}px`,left:r.left+"px",top:r.top+"px"})},Y=(t="",e="span")=>{const o=document.createElement(e),i=document.createTextNode(`${t}`);return o.appendChild(i),o.setAttribute("title",`${t}px`),N(o,"ph-speccer speccer spacing"),o},J=async t=>{if(!t)return;const e=await R(t);if("none"===e.display||"0"===e.opacity||"hidden"===e.visibility)return;const o=(t=>{const{marginTop:e,marginBottom:o,marginLeft:i,marginRight:n,paddingTop:r,paddingBottom:s,paddingLeft:a,paddingRight:p}=t;return{marginTop:e,marginBottom:o,marginLeft:i,marginRight:n,paddingTop:r,paddingBottom:s,paddingLeft:a,paddingRight:p}})(e),i=Object.keys(o).filter((t=>"0px"!==o[t]));if(i.length)for(const e of i){const i=O(o[e]),n=Y(i),r=q(e);N(n,r),document.body.appendChild(n),t.classList.add("is-specced"),await X(e,i,n,t)}},K=t=>{const e=()=>((t,e,o=!1)=>{let i;return function(n,...r){const s=o&&!i;i&&clearTimeout(i),i=setTimeout((function(){i=null,o||t.apply(n,r)}),e),s&&t.apply(n,r)}})((()=>{t()}),300);window.removeEventListener("resize",e),window.addEventListener("resize",e)},Q=t=>{"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{t()})):t()},U=()=>{const t=new IntersectionObserver(((t,e)=>{for(const o of t)o.intersectionRatio>0&&(J(o.target),e.unobserve(o.target))}));for(const e of document.querySelectorAll("[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)"))t.observe(e);const e=new IntersectionObserver(((t,e)=>{for(const o of t)o.intersectionRatio>0&&(_(o.target),e.unobserve(o.target))}));for(const t of document.querySelectorAll("[data-speccer-measure]"))e.observe(t);const o=new IntersectionObserver((async(t,e)=>{for(const o of t)o.intersectionRatio>0&&(await D(o.target),e.unobserve(o.target))}));for(const t of document.querySelectorAll("[data-anatomy-section]"))o.observe(t)},Z=t=>{window.speccer=t},tt=t=>{const e=document.currentScript;if(e){const o=e.getAttribute("src");o&&o.includes("speccer.js")&&(e.hasAttribute("data-manual")?Z(t):e.hasAttribute("data-instant")?t():e.hasAttribute("data-dom")?Q(t):e.hasAttribute("data-lazy")?U():Q(t),e.hasAttribute("data-manual")||e.hasAttribute("data-lazy")||K(t))}},et=(t="span")=>{const e=document.createElement(t),o=I("ph-speccer speccer mark");return N(e,o),e},ot=async t=>{if(!t)return;const e=et();document.body.appendChild(e);const o=await z(e,t),{left:i,top:n,height:r,width:s}=o.absolute(),a={left:`${i}px`,top:`${n}px`,height:`${r}px`,width:`${s}px`};await B(e,a)},it=(t,e=3)=>parseFloat(t+"").toFixed(e),nt=(t,e)=>{const o=document.createElement("div"),i={};null!==e&&""!==e&&(i[e]=!0);const n=I("ph-speccer speccer typography",i);return o.innerHTML=t,N(o,n),o},rt=async e=>{if(!e)return;const o=e.getAttribute("data-speccer-typography"),i=await R(e);if("none"===i.display||"0"===i.opacity||"hidden"===i.visibility)return;e.classList.add("is-specced");const n=await(async t=>{const e=(t=>{const{lineHeight:e,letterSpacing:o,fontFamily:i,fontSize:n,fontStyle:r,fontVariationSettings:s,fontWeight:a}=t;return{lineHeight:e,letterSpacing:o,fontFamily:i,fontSize:n,fontStyle:r,fontVariationSettings:s,fontWeight:a}})(await R(t)),o="normal"!==e.lineHeight?parseInt(e.lineHeight,10)/16+"rem":"normal";return`\nfont-styles: {<ul class="speccer-styles"> <li><span class="property">font-family:</span> ${e.fontFamily};</li> <li><span class="property">font-size:</span> ${e.fontSize} / ${parseInt(e.fontSize,10)/16}rem;</li> <li><span class="property">font-weight:</span> ${e.fontWeight};</li> <li><span class="property">font-variation-settings:</span> ${e.fontVariationSettings};</li> <li><span class="property">line-height:</span> ${e.lineHeight} / ${o};</li> <li><span class="property">letter-spacing:</span> ${e.letterSpacing};</li> <li><span class="property">font-style:</span> ${e.fontStyle};</li></ul>}`})(e),r=nt(n,o);document.body.appendChild(r);const s=await(async(e,o,i)=>{const n=o.getBoundingClientRect(),r=H(i),s=i.getBoundingClientRect(),a=await W(o),p=a.left-s.width-r+"px",c=it(V(a.top,s,n))+"px",l=a.left+n.width+r+"px",h=it(V(a.top,s,n))+"px",d=it(k(a.left,s,n))+"px",f=a.top-s.height-r+"px",m=it(k(a.left,s,n))+"px",u=a.top+n.height+r+"px";let g={left:p,top:c};return e?.includes(t.Right)?g={left:l,top:h}:e?.includes(t.Top)?g={left:d,top:f}:e?.includes(t.Bottom)&&(g={left:m,top:u}),g})(o,e,r);B(r,s)},st={create:Y,element:J},at={create:F,element:D},pt={create:G,element:_},ct={create:et,element:ot},lt={create:nt,element:rt},ht={dom:Q,lazy:U,manual:Z,activate:tt},dt=()=>{((t,e=document)=>{[].forEach.call(e.querySelectorAll(t),(function(t){t.remove()}))})(".ph-speccer.speccer");const t=document.querySelectorAll("[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)"),e=document.querySelectorAll("[data-speccer-measure]"),o=document.querySelectorAll("[data-speccer-typography]"),i=document.querySelectorAll("[data-anatomy-section]"),n=document.querySelectorAll("[data-speccer-mark]");for(const t of n)ot(t);for(const e of t)J(e);for(const t of e)_(t);for(const t of o)rt(t);for(const t of i)D(t)};tt(dt);export{dt as default,at as dissect,ct as mark,pt as measure,ht as modes,st as spacing,lt as typography};
|
|
1
|
+
var t,e,o;!function(t){t.Empty="",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(t||(t={})),function(t){t.Outline="outline",t.Enclose="enclose",t.Full="full",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top",t.SVG="svg",t.Curly="curly"}(e||(e={})),function(t){t.Width="width",t.Height="height",t.Left="left",t.Right="right",t.Bottom="bottom",t.Top="top"}(o||(o={}));const n=t=>t.split(" "),i=t=>n(t).includes(e.Right),r=t=>n(t).includes(e.Bottom),s=t=>n(t).includes(e.Full),a=t=>n(t).includes(e.Enclose),c=t=>t.includes(e.Curly)&&t.includes(e.Full),l=t=>"string"==typeof t,p=t=>!l(t),h=t=>"number"==typeof t,d=t=>!h(t),f=t=>void 0===t,m=()=>new Promise(requestAnimationFrame),u=t=>t.top,g=t=>t.left+t.width,y=t=>t.top+t.height,w=t=>t.left,x=t=>t.left+t.width/2,b=t=>t.top+t.height/2,E={center:t=>({x:x(t),y:b(t)}),top:t=>({x:x(t),y:u(t)}),right:t=>({x:g(t),y:b(t)}),bottom:t=>({x:x(t),y:y(t)}),left:t=>({x:w(t),y:b(t)}),"right-top":t=>({x:g(t),y:u(t)}),"right-bottom":t=>({x:g(t),y:y(t)}),"left-top":t=>({x:w(t),y:u(t)}),"left-bottom":t=>({x:w(t),y:y(t)}),"top-left":t=>({x:w(t),y:u(t)}),"top-right":t=>({x:g(t),y:u(t)}),"bottom-left":t=>({x:w(t),y:y(t)}),"bottom-right":t=>({x:g(t),y:y(t)}),"top-center":t=>({x:x(t),y:u(t)}),"right-center":t=>({x:g(t),y:b(t)}),"bottom-center":t=>({x:x(t),y:y(t)}),"left-center":t=>({x:w(t),y:b(t)})},$=async(t,e="center")=>{if(!e)throw Error("No position given");if(p(e))throw Error("The position given is not the required type: pos: "+typeof e);const o=["center","left","right","top","bottom","right-top","right-bottom","left-top","left-bottom","top-left","top-right","bottom-left","bottom-right","top-center","right-center","bottom-center","left-center"];if(!o.includes(e))throw Error(`The position given does not match allowed positions to use! Valid positions are: ${o.join(", ")}`);await m();const n=t.getBoundingClientRect();return E[e](n)},A=async(t,e,o="center",n="center")=>{if(!t||!e)throw Error("No element given");const{x:i,y:r}=await $(t,o),{x:s,y:a}=await $(e,n);return{x1:i,y1:r,x2:s,y2:a}},v=(t,e)=>{const{x1:o,x2:n,y1:i,y2:r}=t,{direct:s=!1,firstSet:a=!1,direction:c}=e;let l={x:o+(n-o)/2,y:i},p={x:o+(n-o)/2,y:r};return s&&(a?"west"===c?(l={x:o-32,y:i-8},p={x:n+32,y:r}):"south"===c?(l={x:o-8,y:i+32},p={x:n,y:r-32}):"east"===c?(l={x:o+32,y:i-8},p={x:n-32,y:r}):(l={x:o-8,y:i-32},p={x:n,y:r+32}):"west"===c?(l={x:o-32,y:i+8},p={x:n+32,y:r}):"south"===c?(l={x:o+8,y:i+32},p={x:n,y:r-32}):"east"===c?(l={x:o+32,y:i+8},p={x:n-32,y:r}):(l={x:o+8,y:i-32},p={x:n,y:r+32})),{firstPoint:{x:o,y:i},firstControl:l,lastPoint:{x:n,y:r},lastControl:p}},S=async(t,e,o)=>{const{pos1:n,pos2:i,firstSet:r=!1,direction:s}=o,{x1:a,y1:c,x2:l,y2:p}=await A(t,e,n,i);let h=0,d=0;"north"===s?d=8:"west"===s?h=8:"east"===s?h=-8:"south"===s&&(d=-8);const{firstPoint:f,firstControl:m,lastControl:u,lastPoint:g}=v({x1:a+0,x2:l+h,y1:c+0+document.documentElement.scrollTop,y2:p+d+document.documentElement.scrollTop},{direct:!0,firstSet:r,direction:s});return`M ${f.x} ${f.y}C ${m.x} ${m.y}, ${u.x} ${u.y}, ${g.x} ${g.y}`},C=async({start:t,stop:e,crude:o=!1})=>{const{x1:n,y1:i,x2:r,y2:s}=await A(t,e),a=((t,e,o,n,i=!0)=>{if(f(t)||f(e)||f(o)||f(n))throw new SyntaxError("Missing input for `angle`");if(d(t)||d(e)||d(o)||d(n))throw TypeError(`Parameters for \`angle\` do not have the required type. Requires number! Got: ${typeof t} ${typeof e} ${typeof o} ${typeof n}`);const r=n-e,s=o-t;let a=Math.atan2(r,s);return a*=180/Math.PI,i&&a<0&&(a+=360),a})(n,i,r,s);return o?(t=>{if(t>360)throw new RangeError("Parameter cannot exceed 360");if(t<0)throw new RangeError("Parameter cannot be lower than 0");return t>=45&&t<=135?"south":t>135&&t<=225?"west":t>225&&t<=315?"north":"east"})(a):(t=>{if(t>360)throw new RangeError("Parameter cannot exceed 360");if(t<0)throw new RangeError("Parameter cannot be lower than 0");return t>=0&&t<=22.5?"east":t>=22.5&&t<=67.5?"south-east":t>=67.5&&t<=112.5?"south":t>=112.5&&t<=157.5?"south-west":t>=157.5&&t<=202.5?"west":t>=202.5&&t<=247.5?"north-west":t>=247.5&&t<=292.5?"north":t>=292.5&&t<=337.5?"north-east":"east"})(a)},L=()=>"_"+Math.random().toString(36).substring(2,11),P=async(t,e)=>{var o;if(!(!t||!e||l(e)||h(e)||(o=e,"boolean"==typeof o)||Array.isArray(e)&&!e.length||!Object.keys(e).length&&e.constructor===Object))if(await m(),Array.isArray(e))for(const o of e)t.style[o.key]=o.value;else for(const o of Object.keys(e))t.style[o]=e[o]},B=async t=>(await m(),getComputedStyle(t,null));class R{#t;#e;startElement;stopElement;firstPathElement;secondPathElement;constructor(t,e){this.#o(t,e)}#o(t,e){if(!t||!e)throw new Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw new Error("stopElement is not in the DOM");if(!document.body.contains(t))throw new Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,this.#t=document.getElementById("ph-speccer-svg"),this.#e=document.getElementById("ph-speccer-path"),!this.#e||!this.#t)throw new Error("Missing required SVG element to draw lines. Please see the documentation");P(this.#t,{height:`${document.body.scrollHeight}px`}),this.connect()}connect(){this.draw(this.#e)}#n(t){if(!t)throw new Error("No path given to #getPathElement!");const e=`ph_draw_path-path-${L()}`,o=t.cloneNode(!1),n=this.startElement.getAttribute("id")||L();return this.startElement.setAttribute("id",n),o.setAttribute("data-start-el",n),o.setAttribute("id",e),o.classList.remove("original"),o.classList.add("speccer"),o}async draw(t){if(!t)throw new Error("No path given to draw!");const e=this.#n(t),o=this.#n(t);if(!t.parentNode)throw new Error("No parentNode found for path");this.firstPathElement=t.parentNode.insertBefore(e,t.nextSibling),this.secondPathElement=t.parentNode.insertBefore(o,t.nextSibling);const n=await C({stop:this.stopElement,start:this.startElement,crude:!0}),{path1pos1:i,path1pos2:r,path2pos1:s,path2pos2:a}=(t=>{let e,o,n,i;switch(t){case"east":e="right-top",o="left-center",n="right-bottom",i="left-center";break;case"south":e="bottom-left",o="top-center",n="bottom-right",i="top-center";break;case"west":e="left-top",o="right-center",n="left-bottom",i="right-center";break;default:e="top-left",o="bottom-center",n="top-right",i="bottom-center"}return{path1pos1:e,path1pos2:o,path2pos1:n,path2pos2:i}})(n),c=await S(this.startElement,this.stopElement,{pos1:i,pos2:r,firstSet:!0,direction:n}),l=await S(this.startElement,this.stopElement,{pos1:s,pos2:a,direction:n});this.firstPathElement.setAttribute("data-direction",n),this.firstPathElement.setAttribute("data-pos1",i),this.firstPathElement.setAttribute("data-pos2",r),this.firstPathElement.setAttribute("d",c),this.secondPathElement.setAttribute("data-direction",n),this.secondPathElement.setAttribute("data-pos1",s),this.secondPathElement.setAttribute("data-pos2",a),this.secondPathElement.setAttribute("d",l)}}window.DrawSVGCurlyBracket=R;class T{#t;#e;startElement;stopElement;line;constructor(t,e){this.#o(t,e)}#o(t,e){if(!t||!e)throw new Error("Missing inputs startElement and stopElement");if(!document.body.contains(e))throw new Error("stopElement is not in the DOM");if(!document.body.contains(t))throw new Error("startElement is not in the DOM");if(this.startElement=t,this.stopElement=e,this.#t=document.getElementById("ph-speccer-svg"),this.#e=document.getElementById("ph-speccer-path"),!this.#e||!this.#t)throw new Error("Missing required SVG element to draw lines. Please see the documentation");P(this.#t,{height:`${document.body.scrollHeight}px`}),this.connect()}connect(){this.draw(this.#e)}async draw(t){if(!t)throw new Error("No path given to draw!");const e=`ph_draw_path-path-${L()}`,o=t.cloneNode(!1),n=this.startElement.getAttribute("id")||L();if(this.startElement.setAttribute("id",n),o.setAttribute("id",e),o.setAttribute("data-start-el",n),o.classList.remove("original"),o.classList.add("speccer"),!t.parentNode)throw new Error("No parentNode found for path");this.line=t.parentNode.insertBefore(o,t.nextSibling);const i=await C({start:this.startElement,stop:this.stopElement,crude:!0}),{pos1:r,pos2:s}=(t=>{let e,o;switch(t){case"east":e="right",o="left";break;case"south":e="bottom",o="top";break;case"west":e="left",o="right";break;default:e="top",o="bottom"}return{pos1:e,pos2:o}})(i),a=await(async(t,e,o)=>{const{pos1:n,pos2:i}=o,{x1:r,y1:s,x2:a,y2:c}=await A(t,e,n,i),{firstPoint:l,firstControl:p,lastControl:h,lastPoint:d}=v({x1:r,x2:a,y1:s,y2:c},{direction:""});return`M ${l.x} ${l.y}C ${p.x} ${p.y}, ${h.x} ${h.y}, ${d.x} ${d.y}`})(this.startElement,this.stopElement,{pos1:r,pos2:s});this.line.setAttribute("data-direction",i),this.line.setAttribute("data-pos1",r),this.line.setAttribute("data-pos2",s),this.line.setAttribute("d",a)}}window.DrawSVGLine=T;const k=(t,e,o="noop")=>{t&&(!e||e&&!e.length||e.trim().split(" ").filter((t=>t!==o)).forEach((e=>t.classList.add(e))))},N=(t,e)=>t?!e&&p(t)?Object.keys(t).filter((e=>t[e])).join(" ").trim():`${t.trim()} ${e?Object.keys(e).filter((t=>e[t])).join(" "):""}`.trim():"",q=[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ"],I=t=>parseInt(t,10),M=t=>t.includes("Top")?t.replace("Top"," top"):t.includes("Right")?t.replace("Right"," right"):t.includes("Bottom")?t.replace("Bottom"," bottom"):t.includes("Left")?t.replace("Left"," left"):"",O=t=>I(getComputedStyle(t).getPropertyValue("--ph-speccer-pin-space"))||48,H=async(t,e,o)=>{await m();return getComputedStyle(t)[e]===o},V=async(t,e,o)=>{if(!t.parentElement)return null;return await H(t.parentElement,e,o)?t.parentElement:await V(t.parentElement,e,o)},W=(t,e,o)=>t-e.width/2+o.width/2,j=(t,e,o)=>t-e.height/2+o.height/2,z=async t=>{await m();let e=t.getBoundingClientRect(),o=e.top+window.scrollY;const n=e.left+window.scrollX,i=await(async t=>await V(t,"position","sticky"))(t),r=await(async t=>await H(t,"position","sticky"))(t);if(r){const n=t.style.position;await m(),t.style.position="relative",await m(),e=t.getBoundingClientRect(),o=e.top,t.style.position=n}else if(i){const n=i.style.position;await m(),i.style.position="relative",await m(),e=t.getBoundingClientRect(),o=e.top,i.style.position=n}return{height:e.height,width:e.width,top:o,left:n}},F=async(t,e)=>{await m();const o=t.getBoundingClientRect(),n=await z(e),i=await(async(t,e)=>{await m();const o=t.getBoundingClientRect(),n=e.getBoundingClientRect(),i=n.top+window.scrollY,r=n.left+window.scrollX;return{height:n.height,width:n.width,top:j(i,o,n),left:W(r,o,n)}})(t,e),r=n.height,s=n.width,a=o.height,c=o.width;return{absolute:()=>({top:n.top,left:n.left,height:r,width:s}),toTop:({center:t=!1,sourceHeight:e=a,modifier:o=0}={})=>({top:n.top+e+o,left:t?i.left:n.left,height:r,width:s}),fromTop:({center:t=!1,sourceHeight:e=a,modifier:o=0}={})=>({top:n.top-e-o,left:t?i.left:n.left,height:r,width:s}),toBottom:({center:t=!1,sourceHeight:e=a,targetHeight:o=r,modifier:c=0}={})=>({top:n.top+o-(e+c),left:t?i.left:n.left,height:r,width:s}),fromBottom:({center:t=!1,targetHeight:e=r,modifier:o=0}={})=>({top:n.top+e+o,left:t?i.left:n.left,height:r,width:s}),toLeft:({center:t=!1,sourceWidth:e=c,modifier:o=0}={})=>({top:t?i.top:n.top,left:n.left+e+o,height:r,width:s}),fromLeft:({center:t=!1,sourceWidth:e=c,modifier:o=0}={})=>({top:t?i.top:n.top,left:n.left-e-o,height:r,width:s}),toRight:({center:t=!1,sourceWidth:e=c,targetWidth:o=s,modifier:a=0}={})=>({top:t?i.top:n.top,left:n.left+o-(e+a),height:r,width:s}),fromRight:({center:t=!1,targetWidth:e=s,modifier:o=0}={})=>({top:t?i.top:n.top,left:n.left+e+o,height:r,width:s})}},D=async(t,o,c,l)=>{await m();const{isCurly:p=!1}=l||{},h=O(c),d=I(getComputedStyle(c).getPropertyValue("--ph-speccer-measure-size"))||8;const f=await F(c,o);if(a(t)){const{left:t,top:e,height:o,width:n}=f.absolute();return{left:`${t}px`,top:`${e}px`,height:`${o}px`,width:`${n}px`}}if(n(t).includes(e.Left)){if(s(t)&&!p){const{left:t,top:e,height:o}=f.fromLeft({sourceWidth:d});return{left:`${t}px`,top:`${e}px`,height:`${o}px`}}const{left:e,top:o}=f.fromLeft({center:!0,modifier:p?h/1.5:h});return{left:`${e}px`,top:`${o}px`}}if(i(t)){if(s(t)&&!p){const{left:t,top:e,height:o}=f.fromRight({center:!1});return{left:`${t}px`,top:`${e}px`,height:`${o}px`}}const{left:e,top:o}=f.fromRight({center:!0,modifier:p?h/1.5:h});return{left:`${e}px`,top:`${o}px`}}if(r(t)){if(s(t)&&!p){const{left:t,top:e,width:o}=f.fromBottom({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${o}px`}}const{left:e,top:o}=f.fromBottom({center:!0,modifier:p?h/1.5:h});return{left:`${e}px`,top:`${o}px`}}if(s(t)&&!p){const{left:t,top:e,width:o}=f.fromTop({center:!1});return{left:`${t}px`,top:`${e}px`,width:`${o}px`}}const{left:u,top:g}=f.fromTop({center:!0,modifier:p?h/1.5:h});return{left:`${u}px`,top:`${g}px`}},G=(t="",e,o="span")=>{const n=document.createElement(o),i=document.createTextNode(t),r={};null!==e&&""!==e&&(r[e]=!0),!s(e)&&!a(e)||s(e)&&c(e)?n.appendChild(i):(s(e)||a(e))&&n.setAttribute("data-dissection-counter",t);const l=N("ph-speccer speccer dissection",r);return k(n,l),n},_=async t=>{if(!t)return;const o=t.querySelectorAll("[data-anatomy]");if(o){let t=0;o.forEach((async(o,n)=>{if(!o)return;const i=o.getAttribute("data-anatomy")||"";if(!i||""===i||!i.includes(e.Outline))return;let r=q[n];r||(r=`${q[t]}${q[t].toLowerCase()}`,t++);const s=G(r,i);document.body.appendChild(s);const a=await D(i,o,s,{isCurly:c(i)});await P(s,a),i.includes(e.SVG)&&!c(i)?new T(o,s):c(i)&&new R(o,s)}))}},X=(t="",e="",o="span")=>{const n=document.createElement(o);return n.setAttribute("title",`${t}px`),n.setAttribute("data-measure",`${parseInt(`${t}`,10)}px`),k(n,`ph-speccer speccer measure ${e}`),n},Y=async t=>{if(!t)return;const e=t.getAttribute("data-speccer-measure");if(""===e||!e)return;const s=await B(t);if("none"===s.display||"0"===s.opacity||"hidden"===s.visibility)return;await m();const a=t.getBoundingClientRect();if(n(e).includes(o.Width))if(r(e)){const o=X(a.width,e);document.body.appendChild(o);const n=await F(o,t),{left:i,top:r,width:s}=n.fromBottom({center:!1});await P(o,{left:`${i}px`,top:`${r}px`,width:`${s}px`})}else{const o=X(a.width,e);document.body.appendChild(o);const n=await F(o,t),{left:i,top:r,width:s}=n.fromTop({center:!1,modifier:-8});await P(o,{left:`${i}px`,top:`${r}px`,width:`${s}px`})}else if((t=>n(t).includes(o.Height))(e))if(i(e)){const o=X(a.height,e);document.body.appendChild(o);const n=await F(o,t),{left:i,top:r,height:s}=n.fromRight({center:!1});await P(o,{left:`${i}px`,top:`${r}px`,height:`${s}px`})}else{const o=X(a.height,e);document.body.appendChild(o);const n=await F(o,t),{left:i,top:r,height:s}=n.fromLeft({center:!1,modifier:-8});await P(o,{left:`${i}px`,top:`${r}px`,height:`${s}px`})}},J=async(t,e,o,n)=>{await m();const i=n.getBoundingClientRect(),r=await z(n);"marginTop"===t&&P(o,{height:`${e}px`,width:i.width+"px",left:r.left+"px",top:r.top-e+"px"}),"marginRight"===t&&P(o,{height:i.height+"px",width:`${e}px`,left:r.left+parseInt(i.width+"",10)+"px",top:r.top+"px"}),"marginBottom"===t&&P(o,{height:`${e}px`,width:i.width+"px",left:r.left+"px",top:r.top+parseInt(i.height+"",10)+"px"}),"marginLeft"===t&&P(o,{height:i.height+"px",width:`${e}px`,left:r.left-e+"px",top:r.top+"px"}),"paddingTop"===t&&P(o,{height:`${e}px`,width:i.width+"px",left:r.left+"px",top:r.top+"px"}),"paddingBottom"===t&&P(o,{height:`${e}px`,width:i.width+"px",left:r.left+"px",top:r.top+(parseInt(i.height+"",10)-e)+"px"}),"paddingRight"===t&&P(o,{height:i.height+"px",width:`${e}px`,left:r.left+(parseInt(i.width+"",10)-e)+"px",top:r.top+"px"}),"paddingLeft"===t&&P(o,{height:i.height+"px",width:`${e}px`,left:r.left+"px",top:r.top+"px"})},K=(t="",e="span")=>{const o=document.createElement(e),n=document.createTextNode(t+"");return o.appendChild(n),o.setAttribute("title",`${t}px`),k(o,"ph-speccer speccer spacing"),o},Q=async t=>{if(!t)return;const e=await B(t);if("none"===e.display||"0"===e.opacity||"hidden"===e.visibility)return;const o=(t=>{const{marginTop:e,marginBottom:o,marginLeft:n,marginRight:i,paddingTop:r,paddingBottom:s,paddingLeft:a,paddingRight:c}=t;return{marginTop:e,marginBottom:o,marginLeft:n,marginRight:i,paddingTop:r,paddingBottom:s,paddingLeft:a,paddingRight:c}})(e),n=Object.keys(o).filter((t=>"0px"!==o[t]));if(n.length)for(const e of n){const n=I(o[e]),i=K(n),r=M(e);k(i,r),document.body.appendChild(i),t.classList.add("is-specced"),await J(e,n,i,t)}},U=t=>{const e=()=>((t,e,o=!1)=>{let n;return function(i,...r){const s=o&&!n;n&&clearTimeout(n),n=setTimeout((function(){n=null,o||t.apply(i,r)}),e),s&&t.apply(i,r)}})((()=>{t()}),300);window.removeEventListener("resize",e),window.addEventListener("resize",e)},Z=t=>{"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>{t()})):t()},tt=()=>{const t=new IntersectionObserver(((t,e)=>{for(const o of t)o.intersectionRatio>0&&(Q(o.target),e.unobserve(o.target))}));for(const e of document.querySelectorAll("[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)"))t.observe(e);const e=new IntersectionObserver(((t,e)=>{for(const o of t)o.intersectionRatio>0&&(Y(o.target),e.unobserve(o.target))}));for(const t of document.querySelectorAll("[data-speccer-measure]"))e.observe(t);const o=new IntersectionObserver((async(t,e)=>{for(const o of t)o.intersectionRatio>0&&(await _(o.target),e.unobserve(o.target))}));for(const t of document.querySelectorAll("[data-anatomy-section]"))o.observe(t)},et=t=>{window.speccer=t},ot=t=>{const e=document.currentScript;if(e){const o=e.getAttribute("src");o?.includes("speccer.js")&&(e.hasAttribute("data-manual")?et(t):e.hasAttribute("data-instant")?t():e.hasAttribute("data-dom")?Z(t):e.hasAttribute("data-lazy")?tt():Z(t),e.hasAttribute("data-manual")||e.hasAttribute("data-lazy")||U(t))}},nt=["alt","altgraph","capslock","control","fn","fnlock","hyper","meta","numlock","os","scrolllock","shift","super","symbol","command","ctrl","altgr","symbollock"],it=["escape","esc","enter","return","⏎","␛"],rt=async(t,e,o)=>{await m();const n=O(o),i=await F(o,e);if("tabstops"===t){let{left:t,top:e}=i.fromTop();return t-=32,t<=0&&(t=32),e<=0&&(e=32),{left:`${t}px`,top:`${e}px`}}if("landmark"===t){let{left:t,top:e}=i.fromTop();return t-=16,e-=16,t<=0&&(t=32),e<=0&&(e=32),{left:`${t}px`,top:`${e}px`}}if("region"===t){const{left:t,top:e,height:o,width:n}=i.fromTop();return{height:`${o}px`,width:`${n}px`,left:`${t}px`,top:`${e}px`}}if("shortcut"===t){const{left:t,top:e}=i.fromBottom();return{left:`${t}px`,top:`${e}px`}}const{left:r,top:s}=i.fromTop({center:!0,modifier:n});return{left:r-32+"px",top:s-32+"px"}},st=async(t,e,o)=>{if(!t||!t.checkVisibility())return;const n=((t="tabstops",e,o="span")=>{const n=document.createElement(o),i=N("ph-speccer speccer a11y",{tabstops:"tabstops"===t,landmark:"landmark"===t,region:"region"===t});if("landmark"===t&&e){const t=document.createTextNode(e+"");n.appendChild(t)}return k(n,i),n})(o,e);if("landmark"===o){n.setAttribute("data-speccer-nodename",t.nodeName);const e=t.role||`semantic role: ${t.nodeName.toLowerCase()}`,o=t.getAttribute("aria-label")||"unnamed";n.setAttribute("title",`${o}: ${e}`)}document.body.appendChild(n);const i=await rt(o,t,n);await P(n,i)},at=async(t,e)=>{const o=e.split(/\s\+\s/).map((t=>t.trim())),n=document.createElement("div");n.classList.add("ph-speccer"),n.classList.add("speccer"),n.classList.add("a11y"),n.classList.add("shortcut-holder");for(const t of o){const e=document.createElement("kbd"),o=document.createTextNode(t);e.classList.add("ph-speccer"),e.classList.add("speccer"),e.classList.add("a11y"),e.classList.add("shortcut"),nt.includes(t.toLowerCase())&&e.classList.add("modifier"),it.includes(t.toLowerCase())&&e.classList.add("physical"),e.appendChild(o),n.appendChild(e)}document.body.appendChild(n);const i=await rt("shortcut",t,n);await P(n,i)},ct=(t="span")=>{const e=document.createElement(t),o=N("ph-speccer speccer mark");return k(e,o),e},lt=async t=>{if(!t)return;const e=ct();document.body.appendChild(e);const o=await F(e,t),{left:n,top:i,height:r,width:s}=o.absolute(),a={left:`${n}px`,top:`${i}px`,height:`${r}px`,width:`${s}px`};await P(e,a)},pt=(t,e=3)=>parseFloat(t+"").toFixed(e),ht=(t,e)=>{const o=document.createElement("div"),n={};null!==e&&""!==e&&(n[e]=!0);const i=N("ph-speccer speccer typography",n);return o.innerHTML=t,k(o,i),o},dt=async e=>{if(!e)return;const o=e.getAttribute("data-speccer-typography"),n=await B(e);if("none"===n.display||"0"===n.opacity||"hidden"===n.visibility)return;e.classList.add("is-specced");const i=await(async t=>{const e=(t=>{const{lineHeight:e,letterSpacing:o,fontFamily:n,fontSize:i,fontStyle:r,fontVariationSettings:s,fontWeight:a}=t;return{lineHeight:e,letterSpacing:o,fontFamily:n,fontSize:i,fontStyle:r,fontVariationSettings:s,fontWeight:a}})(await B(t)),o="normal"!==e.lineHeight?parseInt(e.lineHeight,10)/16+"rem":"normal";return`\nfont-styles: {<ul class="speccer-styles"> <li><span class="property">font-family:</span> ${e.fontFamily};</li> <li><span class="property">font-size:</span> ${e.fontSize} / ${parseInt(e.fontSize,10)/16}rem;</li> <li><span class="property">font-weight:</span> ${e.fontWeight};</li> <li><span class="property">font-variation-settings:</span> ${e.fontVariationSettings};</li> <li><span class="property">line-height:</span> ${e.lineHeight} / ${o};</li> <li><span class="property">letter-spacing:</span> ${e.letterSpacing};</li> <li><span class="property">font-style:</span> ${e.fontStyle};</li></ul>}`})(e),r=ht(i,o);document.body.appendChild(r);const s=await(async(e,o,n)=>{const i=o.getBoundingClientRect(),r=O(n),s=n.getBoundingClientRect(),a=await z(o),c=a.left-s.width-r+"px",l=pt(j(a.top,s,i))+"px",p=a.left+i.width+r+"px",h=pt(j(a.top,s,i))+"px",d=pt(W(a.left,s,i))+"px",f=a.top-s.height-r+"px",m=pt(W(a.left,s,i))+"px",u=a.top+i.height+r+"px";let g={left:c,top:l};return e?.includes(t.Right)?g={left:p,top:h}:e?.includes(t.Top)?g={left:d,top:f}:e?.includes(t.Bottom)&&(g={left:m,top:u}),g})(o,e,r);P(r,s)},ft={create:K,element:Q},mt={create:G,element:_},ut={create:X,element:Y},gt={create:ct,element:lt},yt={create:ht,element:dt},wt={dom:Z,lazy:tt,manual:et,activate:ot},xt=()=>{((t,e=document)=>{[].forEach.call(e.querySelectorAll(t),(function(t){t.remove()}))})(".ph-speccer.speccer");const t=document.querySelectorAll("[data-speccer],[data-speccer] *:not(td):not(tr):not(th):not(tfoot):not(thead):not(tbody)"),e=document.querySelectorAll("[data-speccer-measure]"),o=document.querySelectorAll("[data-speccer-typography]"),n=document.querySelectorAll("[data-anatomy-section]"),i=document.querySelectorAll("[data-speccer-mark]");for(const t of i)lt(t);for(const e of t)Q(e);for(const t of e)Y(t);for(const t of o)dt(t);for(const t of n)_(t);(()=>{const t=document.querySelectorAll("[data-speccer-a11y-tabstops]"),e=document.querySelectorAll("[data-speccer-a11y-landmark]"),o=document.querySelectorAll("[data-speccer-a11y-shortcut]");if(o.length)for(const t of o){const e=t.getAttribute("data-speccer-a11y-shortcut");e&&""!==e&&at(t,e)}if(t.length)for(const e of t){const t=e.querySelectorAll("\n a[href], area[href], input:not([disabled]):not([tabindex='-1']),\n button:not([disabled]):not([tabindex='-1']),select:not([disabled]):not([tabindex='-1']),\n textarea:not([disabled]):not([tabindex='-1']),\n iframe, object, embed, *[tabindex]:not([tabindex='-1']), *[contenteditable=true]\n");for(const e of t)st(e,null,"tabstops")}if(e.length)for(const t of e){const e=t.querySelectorAll('\nheader, footer, section, main, nav, aside, [role="section"], [role="banner"],\n[role="complementary"], [role="contentinfo"], [role="form"], [role="main"],\n[role="navigation"], [role="region"], [role="search"]\n');for(const[t,o]of e.entries())st(o,t+1,"landmark"),st(o,null,"region")}})()};ot(xt);export{xt as default,mt as dissect,gt as mark,ut as measure,wt as modes,ft as spacing,yt as typography};
|
|
2
2
|
//# sourceMappingURL=speccer.esm.js.map
|