@xiee/utils 1.4.2 → 1.5.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 +5 -0
- package/css/copy-button.css +21 -0
- package/css/copy-button.min.css +1 -0
- package/js/copy-button.js +22 -0
- package/js/copy-button.min.js +1 -0
- package/js/fold-details.js +4 -3
- package/js/fold-details.min.js +1 -1
- package/js/fullwidth.js +1 -1
- package/js/fullwidth.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,6 +32,11 @@ Then the image will have a tooltip on mouseover.
|
|
|
32
32
|
Center `<img>`, `<video>`, and `<object>` on a page if they are the only child
|
|
33
33
|
of their parent element.
|
|
34
34
|
|
|
35
|
+
## copy-button.js
|
|
36
|
+
|
|
37
|
+
Add a copy button to any element (by default, `<pre>` code blocks) on a page.
|
|
38
|
+
See [this post](https://yihui.org/en/2023/09/copy-button/) for details.
|
|
39
|
+
|
|
35
40
|
## external-link.js
|
|
36
41
|
|
|
37
42
|
If a link of `<a>` does not start with `http://` or `https://`, add the
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.copy-button {
|
|
2
|
+
position: absolute;
|
|
3
|
+
display: none;
|
|
4
|
+
cursor: pointer;
|
|
5
|
+
inset: 5px 5px auto auto;
|
|
6
|
+
width: 1em;
|
|
7
|
+
height: 1em;
|
|
8
|
+
border: 1px solid;
|
|
9
|
+
box-shadow: -3px 3px #999;
|
|
10
|
+
}
|
|
11
|
+
:hover > .copy-button {
|
|
12
|
+
display: inline-block;
|
|
13
|
+
}
|
|
14
|
+
.copy-success {
|
|
15
|
+
box-shadow: none;
|
|
16
|
+
background-color: #999;
|
|
17
|
+
transition: box-shadow 300ms ease-out, background-color 300ms ease-out;
|
|
18
|
+
}
|
|
19
|
+
.copy-fail {
|
|
20
|
+
border-style: dotted;
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.copy-button{position:absolute;display:none;cursor:pointer;inset:5px 5px auto auto;width:1em;height:1em;border:1px solid;box-shadow:-3px 3px #999}:hover>.copy-button{display:inline-block}.copy-success{box-shadow:none;background-color:#999;transition:box-shadow .3s ease-out,background-color .3s ease-out}.copy-fail{border-style:dotted}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// add a button to elements to copy their content: https://yihui.org/en/2023/09/copy-button/
|
|
2
|
+
(d => {
|
|
3
|
+
const cfg = d.currentScript?.dataset;
|
|
4
|
+
d.querySelectorAll(cfg?.selector || 'pre>code').forEach(el => {
|
|
5
|
+
const btn = d.createElement('span'), cls = btn.classList,
|
|
6
|
+
c1 = 'copy-success', c2 = 'copy-fail';
|
|
7
|
+
btn.className = 'copy-button';
|
|
8
|
+
// temporarily add a class to the button (as a feedback to copy action)
|
|
9
|
+
function feedback(c) {
|
|
10
|
+
cls.add(c); setTimeout(() => cls.remove(c), 1000);
|
|
11
|
+
}
|
|
12
|
+
btn.onclick = () => navigator.clipboard.writeText(el.innerText).then(
|
|
13
|
+
() => feedback(c1), () => feedback(c2)
|
|
14
|
+
);
|
|
15
|
+
// add the button to <pre> for <code> because <code>'s innerHTML' may be
|
|
16
|
+
// changed later, e.g., by syntax highlighting libraries
|
|
17
|
+
const p = (el.tagName === 'CODE' && el?.parentNode.tagName === 'PRE') ? el.parentNode : el;
|
|
18
|
+
// add the button only if it has not been added
|
|
19
|
+
p.querySelector('.copy-button') || p.append(btn);
|
|
20
|
+
getComputedStyle(p).position === 'static' && (p.style.position = 'relative');
|
|
21
|
+
});
|
|
22
|
+
})(document);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(e=>{const t=e.currentScript?.dataset;e.querySelectorAll(t?.selector||"pre>code").forEach((t=>{const o=e.createElement("span"),c=o.classList;function a(e){c.add(e),setTimeout((()=>c.remove(e)),1e3)}o.className="copy-button",o.onclick=()=>navigator.clipboard.writeText(t.innerText).then((()=>a("copy-success")),(()=>a("copy-fail")));const n="CODE"===t.tagName&&"PRE"===t?.parentNode.tagName?t.parentNode:t;n.querySelector(".copy-button")||n.append(o),"static"===getComputedStyle(n).position&&(n.style.position="relative")}))})(document);
|
package/js/fold-details.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// fold elements with <details>: https://yihui.org/en/2023/09/code-folding/
|
|
2
2
|
(d => {
|
|
3
|
-
const cfg = d.currentScript?.dataset, cls = 'folder';
|
|
3
|
+
const cfg = d.currentScript?.dataset, cls = 'folder'; let status = !!cfg?.open;
|
|
4
4
|
d.querySelectorAll(cfg?.selector || 'pre>code[class],pre[class]').forEach(el => {
|
|
5
5
|
const s1 = d.createElement('details'), s2 = d.createElement('summary');
|
|
6
|
-
s1.className = cls; s1.open =
|
|
6
|
+
s1.className = cls; s1.open = status;
|
|
7
7
|
s2.innerText = (cfg?.label || 'Details') + (cfg?.tagName ? ` <${el.tagName}>` : '');
|
|
8
8
|
// special case: for <code>, put its parent <pre> inside <details>
|
|
9
9
|
if (el.tagName === 'CODE' && el.parentNode.tagName === 'PRE') el = el.parentNode;
|
|
@@ -24,8 +24,9 @@
|
|
|
24
24
|
p.insertAdjacentElement(cfg.position || 'afterbegin', btn);
|
|
25
25
|
}
|
|
26
26
|
btn.onclick = (e) => {
|
|
27
|
+
status = !status;
|
|
27
28
|
d.querySelectorAll(`details.${cls}`).forEach(el => {
|
|
28
|
-
el.
|
|
29
|
+
el.open = status;
|
|
29
30
|
});
|
|
30
31
|
};
|
|
31
32
|
})(document);
|
package/js/fold-details.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(e=>{const t=e.currentScript?.dataset,a="folder";if(e.querySelectorAll(t?.selector||"pre>code[class],pre[class]").forEach((
|
|
1
|
+
(e=>{const t=e.currentScript?.dataset,a="folder";let r=!!t?.open;if(e.querySelectorAll(t?.selector||"pre>code[class],pre[class]").forEach((n=>{const l=e.createElement("details"),o=e.createElement("summary");l.className=a,l.open=r,o.innerText=(t?.label||"Details")+(t?.tagName?` <${n.tagName}>`:""),"CODE"===n.tagName&&"PRE"===n.parentNode.tagName&&(n=n.parentNode),l.append(o),n.before(l),l.append(n)})),!t?.hasOwnProperty("button"))return;const n=e.querySelector(t.parent);let l=e.querySelector(t.button);(l||n)&&(l||(l=e.createElement("button"),l.id="toggle-all",l.innerText=t.buttonLabel||"Toggle Details",n.insertAdjacentElement(t.position||"afterbegin",l)),l.onclick=t=>{r=!r,e.querySelectorAll(`details.${a}`).forEach((e=>{e.open=r}))})})(document);
|
package/js/fullwidth.js
CHANGED
|
@@ -6,7 +6,7 @@ document.querySelectorAll('pre,table,#TableOfContents').forEach(node => {
|
|
|
6
6
|
switch (node.tagName) {
|
|
7
7
|
case 'PRE':
|
|
8
8
|
const el = node.firstElementChild;
|
|
9
|
-
el?.tagName === 'CODE' && el.scrollWidth > el.offsetWidth && fullwidth(el);
|
|
9
|
+
el?.tagName === 'CODE' && el.scrollWidth > el.offsetWidth && fullwidth(el.parentNode);
|
|
10
10
|
break;
|
|
11
11
|
case 'TABLE':
|
|
12
12
|
const p = node.parentElement;
|
package/js/fullwidth.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
document.querySelectorAll("pre,table,#TableOfContents").forEach((t=>{function e(t){t.classList.add("fullwidth")}switch(t.tagName){case"PRE":const l=t.firstElementChild;"CODE"===l?.tagName&&l.scrollWidth>l.offsetWidth&&e(l);break;case"TABLE":const a=t.parentElement;a&&a.offsetWidth<t.offsetWidth&&e(t);break;default:t.querySelectorAll("a").forEach((l=>{!t.classList.contains("fullwidth")&&l.getClientRects().length>1&&e(t)}))}}));
|
|
1
|
+
document.querySelectorAll("pre,table,#TableOfContents").forEach((t=>{function e(t){t.classList.add("fullwidth")}switch(t.tagName){case"PRE":const l=t.firstElementChild;"CODE"===l?.tagName&&l.scrollWidth>l.offsetWidth&&e(l.parentNode);break;case"TABLE":const a=t.parentElement;a&&a.offsetWidth<t.offsetWidth&&e(t);break;default:t.querySelectorAll("a").forEach((l=>{!t.classList.contains("fullwidth")&&l.getClientRects().length>1&&e(t)}))}}));
|