From 65a70a54405209dfe7201f91ffe9eb0ab2389ccf Mon Sep 17 00:00:00 2001 From: Jonny Barnes Date: Sun, 17 Dec 2023 14:15:45 +0000 Subject: [PATCH] =?UTF-8?q?Add=20some=20snow=20=E2=9D=84=EF=B8=8Fi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also get to play with some web components --- package-lock.json | 28 ++ package.json | 6 +- public/assets/app.css | 2 +- public/assets/app.css.br | Bin 1347 -> 1333 bytes public/assets/frontend/is-land.js | 338 +++++++++++++++++++++++++ public/assets/frontend/is-land.js.br | Bin 0 -> 2690 bytes public/assets/frontend/snow-fall.js | 117 +++++++++ public/assets/frontend/snow-fall.js.br | Bin 0 -> 1129 bytes resources/views/master.blade.php | 7 + 9 files changed, 496 insertions(+), 2 deletions(-) create mode 100644 public/assets/frontend/is-land.js create mode 100644 public/assets/frontend/is-land.js.br create mode 100644 public/assets/frontend/snow-fall.js create mode 100644 public/assets/frontend/snow-fall.js.br diff --git a/package-lock.json b/package-lock.json index 02099435..e36fb622 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,10 @@ "name": "jbuk-frontend", "version": "0.0.1", "license": "CC0-1.0", + "dependencies": { + "@11ty/is-land": "^4.0.0", + "@zachleat/snow-fall": "^1.0.2" + }, "devDependencies": { "@babel/core": "^7.23.6", "@babel/preset-env": "^7.23.6", @@ -35,6 +39,15 @@ "webpack-cli": "^5.1.4" } }, + "node_modules/@11ty/is-land": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@11ty/is-land/-/is-land-4.0.0.tgz", + "integrity": "sha512-RxbjF2+FzSu3rerHrWLRsvsPX2YM47RwXpdWCCzLhwRSsz5sJe9TnK7mphEld1gZnp2GeD5ByvhqjIc4CqidsQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -2591,6 +2604,11 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "node_modules/@zachleat/snow-fall": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@zachleat/snow-fall/-/snow-fall-1.0.2.tgz", + "integrity": "sha512-nyNeliowryq+roSMktyV3o14DduSuU4BvBzruVSPV6e8U8Eid2zNzSj1AzCQByPId7Q4MrIP2QWL2UHeHGfmcA==" + }, "node_modules/acorn": { "version": "8.9.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", @@ -7566,6 +7584,11 @@ } }, "dependencies": { + "@11ty/is-land": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@11ty/is-land/-/is-land-4.0.0.tgz", + "integrity": "sha512-RxbjF2+FzSu3rerHrWLRsvsPX2YM47RwXpdWCCzLhwRSsz5sJe9TnK7mphEld1gZnp2GeD5ByvhqjIc4CqidsQ==" + }, "@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -9353,6 +9376,11 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, + "@zachleat/snow-fall": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@zachleat/snow-fall/-/snow-fall-1.0.2.tgz", + "integrity": "sha512-nyNeliowryq+roSMktyV3o14DduSuU4BvBzruVSPV6e8U8Eid2zNzSj1AzCQByPId7Q4MrIP2QWL2UHeHGfmcA==" + }, "acorn": { "version": "8.9.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", diff --git a/package.json b/package.json index 68337dbc..e21d362a 100644 --- a/package.json +++ b/package.json @@ -39,5 +39,9 @@ "> 1%", "not IE 11", "not IE_Mob 11" - ] + ], + "dependencies": { + "@11ty/is-land": "^4.0.0", + "@zachleat/snow-fall": "^1.0.2" + } } diff --git a/public/assets/app.css b/public/assets/app.css index c935785f..fc94aaab 100644 --- a/public/assets/app.css +++ b/public/assets/app.css @@ -1 +1 @@ -:root{--font-family-headings:"Archer SSm A","Archer SSm B",serif;--font-family-body:"Verlag A","Verlag B",sans-serif;--font-family-monospace:"Operator Mono SSm A","Operator Mono SSm B",monospace;--font-size-sm:0.75rem;--font-size-base:1rem;--font-size-md:1.25rem;--font-size-lg:1.5rem;--font-size-xl:1.75rem;--font-size-xxl:2rem;--font-size-xxxl:2.25rem;--color-primary:#334700;--color-secondary:#e3ffb7;--color-link:#00649e;--color-link-visited:#bc7aff;--color-primary-shadow:rgba(16,25,0,.4)}@supports (color:color(display-p3 0 0 0)){:root{--color-primary:color(display-p3 0.21567 0.27838 0.03615)}}@supports (color:oklab(0% 0 0)){:root{--color-primary:oklch(36.8% 0.1 125.505deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-secondary:color(display-p3 0.91016 0.99842 0.74082)}}@supports (color:oklab(0% 0 0)){:root{--color-secondary:oklch(96.3% 0.1 125.505deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-link:color(display-p3 0.01045 0.38351 0.63618)}}@supports (color:oklab(0% 0 0)){:root{--color-link:oklch(48.09% 0.146 241.41deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-link-visited:color(display-p3 0.70467 0.47549 0.99958)}}@supports (color:oklab(0% 0 0)){:root{--color-link-visited:oklch(70.44% 0.21 304.41deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-primary-shadow:color(display-p3 0.06762 0.09646 0.00441/0.4)}}@supports (color:oklab(0% 0 0)){:root{--color-primary-shadow:oklch(19.56% 0.054 125.505deg/40%)}}body{background-color:var(--color-secondary);color:var(--color-primary);font-family:var(--font-family-body);font-size:var(--font-size-md)}code{font-family:var(--font-family-monospace)}h1,h2,h3,h4,h5,h6{font-family:var(--font-family-headings)}.grid{display:grid;grid-template-columns:5vw 1fr 5vw;grid-template-rows:-webkit-min-content 1fr -webkit-min-content;grid-template-rows:min-content 1fr min-content;row-gap:1rem}#site-header{grid-column:2/3;grid-row:1/2}main{grid-column:2/3;grid-row:2/3}.h-feed{-webkit-box-orient:vertical;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;gap:2rem}.h-entry h1:first-of-type,.h-entry p:first-of-type{-webkit-margin-before:0;margin-block-start:0}.pagination{-webkit-margin-before:1rem;margin-block-start:1rem}footer{grid-column:2/3;grid-row:3/4}footer .iwc-logo{max-width:85vw}footer .footer-actions{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;gap:1rem}a{color:var(--color-link)}a:visited{color:var(--color-link-visited)}#site-header a:visited,a.auth:visited{color:var(--color-link)}.hljs{border-radius:.5rem}.h-card .hovercard{-webkit-box-orient:vertical;-webkit-box-direction:normal;background-color:var(--color-secondary);border-radius:1rem;-webkit-box-shadow:0 .5rem .5rem .5rem var(--color-primary-shadow);box-shadow:0 .5rem .5rem .5rem var(--color-primary-shadow);display:none;-ms-flex-direction:column;flex-direction:column;gap:.5rem;opacity:0;padding:1rem;position:absolute;-webkit-transition:opacity .5s ease-in-out;transition:opacity .5s ease-in-out;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;z-index:100}.h-card .hovercard .u-photo{max-width:6rem}.h-card .hovercard .social-icon{height:1rem;width:1rem}.h-card:hover .hovercard{display:-webkit-box;display:-ms-flexbox;display:flex;opacity:1}.h-entry{-webkit-border-start:1px solid var(--color-primary);-webkit-padding-start:.5rem;border-inline-start:1px solid var(--color-primary);padding-inline-start:.5rem}.h-entry .reply-to{font-style:italic}.h-entry .post-info a{text-decoration:none}.h-entry .note-metadata{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;gap:1rem}.h-entry .note-metadata .likes,.h-entry .note-metadata .replies,.h-entry .note-metadata .reposts{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-ms-flex-direction:row;flex-direction:row;gap:.5rem}.h-entry .note-metadata .syndication-links{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.h-entry .note-metadata .syndication-links a{text-decoration:none}.h-entry .note-metadata .syndication-links a svg{height:1rem;width:1rem}.feather{stroke:currentcolor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;fill:none;height:24px;width:24px}.sr-only{clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}main>.u-comment{-webkit-margin-before:2rem;-webkit-margin-start:2rem;-webkit-border-start:1px solid var(--color-primary);-webkit-padding-start:.5rem;border-inline-start:1px solid var(--color-primary);margin-block-start:2rem;margin-inline-start:2rem;padding-inline-start:.5rem}main>.u-comment .mini-h-card{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-ms-flex-direction:row;flex-direction:row}main>.u-comment .mini-h-card .u-photo{-webkit-margin-after:.5rem;border-radius:50%;height:2rem;margin-block-end:.5rem;width:2rem}main .notes-subtitle{font-size:1.2rem;font-weight:600}main .webmentions-author-list{-webkit-box-orient:horizontal;-webkit-box-direction:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;gap:1rem}main .webmentions-author-list img{border-radius:50%;height:4rem;width:4rem} +:root{--font-family-headings:"Archer SSm A","Archer SSm B",serif;--font-family-body:"Verlag A","Verlag B",sans-serif;--font-family-monospace:"Operator Mono SSm A","Operator Mono SSm B",monospace;--font-size-sm:0.75rem;--font-size-base:1rem;--font-size-md:1.25rem;--font-size-lg:1.5rem;--font-size-xl:1.75rem;--font-size-xxl:2rem;--font-size-xxxl:2.25rem;--color-primary:#334700;--color-secondary:#e3ffb7;--color-link:#00649e;--color-link-visited:#bc7aff;--color-primary-shadow:rgba(16,25,0,.4)}@supports (color:color(display-p3 0 0 0)){:root{--color-primary:color(display-p3 0.21567 0.27838 0.03615)}}@supports (color:oklab(0% 0 0)){:root{--color-primary:oklch(36.8% 0.1 125.505deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-secondary:color(display-p3 0.91016 0.99842 0.74082)}}@supports (color:oklab(0% 0 0)){:root{--color-secondary:oklch(96.3% 0.1 125.505deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-link:color(display-p3 0.01045 0.38351 0.63618)}}@supports (color:oklab(0% 0 0)){:root{--color-link:oklch(48.09% 0.146 241.41deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-link-visited:color(display-p3 0.70467 0.47549 0.99958)}}@supports (color:oklab(0% 0 0)){:root{--color-link-visited:oklch(70.44% 0.21 304.41deg)}}@supports (color:color(display-p3 0 0 0)){:root{--color-primary-shadow:color(display-p3 0.06762 0.09646 0.00441/0.4)}}@supports (color:oklab(0% 0 0)){:root{--color-primary-shadow:oklch(19.56% 0.054 125.505deg/40%)}}body{background-color:var(--color-secondary);color:var(--color-primary);font-family:var(--font-family-body);font-size:var(--font-size-md)}code{font-family:var(--font-family-monospace)}h1,h2,h3,h4,h5,h6{font-family:var(--font-family-headings)}.grid{display:grid;grid-template-columns:5vw 1fr 5vw;grid-template-rows:-webkit-min-content 1fr -webkit-min-content;grid-template-rows:min-content 1fr min-content;row-gap:1rem}#site-header{grid-column:2/3;grid-row:1/2}main{grid-column:2/3;grid-row:2/3}.h-feed{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;gap:2rem}.h-entry h1:first-of-type,.h-entry p:first-of-type{-webkit-margin-before:0;margin-block-start:0}.pagination{-webkit-margin-before:1rem;margin-block-start:1rem}footer{grid-column:2/3;grid-row:3/4}footer .iwc-logo{max-width:85vw}footer .footer-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;gap:1rem}a{color:var(--color-link)}a:visited{color:var(--color-link-visited)}#site-header a:visited,a.auth:visited{color:var(--color-link)}.hljs{border-radius:.5rem}.h-card .hovercard{background-color:var(--color-secondary);border-radius:1rem;-webkit-box-shadow:0 .5rem .5rem .5rem var(--color-primary-shadow);box-shadow:0 .5rem .5rem .5rem var(--color-primary-shadow);display:none;opacity:0;padding:1rem;position:absolute;-webkit-transition:opacity .5s ease-in-out;transition:opacity .5s ease-in-out;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;z-index:100;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;gap:.5rem}.h-card .hovercard .u-photo{max-width:6rem}.h-card .hovercard .social-icon{height:1rem;width:1rem}.h-card:hover .hovercard{display:-webkit-box;display:-ms-flexbox;display:flex;opacity:1}.h-entry{-webkit-border-start:1px solid var(--color-primary);border-inline-start:1px solid var(--color-primary);-webkit-padding-start:.5rem;padding-inline-start:.5rem}.h-entry .reply-to{font-style:italic}.h-entry .post-info a{text-decoration:none}.h-entry .note-metadata{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;gap:1rem}.h-entry .note-metadata .likes,.h-entry .note-metadata .replies,.h-entry .note-metadata .reposts{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;gap:.5rem;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.h-entry .note-metadata .syndication-links{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.h-entry .note-metadata .syndication-links a{text-decoration:none}.h-entry .note-metadata .syndication-links a svg{height:1rem;width:1rem}.feather{height:24px;width:24px;stroke:currentcolor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;fill:none}.sr-only{clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}main>.u-comment{-webkit-margin-before:2rem;margin-block-start:2rem;-webkit-margin-start:2rem;margin-inline-start:2rem;-webkit-border-start:1px solid var(--color-primary);border-inline-start:1px solid var(--color-primary);-webkit-padding-start:.5rem;padding-inline-start:.5rem}main>.u-comment .mini-h-card{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}main>.u-comment .mini-h-card .u-photo{border-radius:50%;height:2rem;width:2rem;-webkit-margin-after:.5rem;margin-block-end:.5rem}main .notes-subtitle{font-size:1.2rem;font-weight:600}main .webmentions-author-list{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;gap:1rem}main .webmentions-author-list img{border-radius:50%;height:4rem;width:4rem} diff --git a/public/assets/app.css.br b/public/assets/app.css.br index 9f5f9941e06e6bd9556445dadfb91bd2b7450d36..1c6315eb78f45b46b359c40cbcc5272c1e7889e1 100644 GIT binary patch literal 1333 zcmV-51m!JiO5#XM?GhOlkZQp{gx@M%3r7e@iwJ4{4N`oQ>$tzLAtpV zme2iHUsP+~+QtbB@FnyeG-dVX{?}5VeQ^;oawANH1u`y@gu5HqIrhs_TV~hh z`63uW&R3SDZDU-8tT48Z(QF+GSRA$Zc)_N4pYnSBX#j`5{IW;`O4&$Ie?HasV6}*T z9-@=rDvJ)q97KbTrRN%ro&t*BfB@dg!H>S?8RR6IwC4AhFWSn9egre22;K3yhy#J5 z6&bRiuP#fxeCXjyOaWn}uNUD(B`c^oE(5j~2AA{v1uF#~Q}9CxRx zH~}YRE`tKD`RFjvnd?LD%G35#mBW(tQ>fGhYxY&J6;`D4`laTJdR3%HPP57eOuHU# zm(1sxH#BVvWd{mu9v?TwBbz2b50uiGAdG#V&ojPDTxX)aila#=9->8X@*YB=+FDR4p zT3FU>MI50XV~wV{_jArBC2?z-BS`fb3fvRu%AUN;a}19jVq{l;7XVdmKsrT8dEBUG z&SZWwOgZbJR(p)+|6liFgmv!zROOxy3KI6N zbU`K31JaJQg@4%e!JZLSFAqpN*&>wjb6U$}h3I_GDkby5S*q$pl{^cZ1I=#;b9904 zGuQCO>R16^;eReC%hOD&a;^+nT_xC3iwSKST02D;H>(Jh9Cj$*MrQqQU2$~C#!cDl zi=|Px9n{j@OW0#|@i4U;^nxA!-EF@ARbgLX; zaQvrd8SEhzgd(MwOIa9sA0@X{GsBbDd>qh{qL|6}NX`wXGfm0X@)~~`p*bY4mB}5x zKV1{|t^@?%vw(os6*)VVKKTE;(I>$miLabkI;N`rYf{VJbrKgK*m>vR&Tuj`1P@85 zJ2)%cD>DCMItLj=6U9FakK@WhQ0HJm5s?kPr0n0R_zZNQin!r1w-16r(2hq?_rjA+ zK3;V?p3H7jnV*WkS_bWT5>AZ-7!2T5)6?C%6nrNX_Q46C(;Xm_Bw&%1B~PR=RR)BV zcn!fdZo_+Z0el1uA|n6&Ll8v_!->jDUG`}zg{_(25S+q&sub0|Uu2R64ry$X zZB;F%xtZ8*psV0rx~m{7KYlF*+MJ7!ksDzmY+Q_sB;jsn=KVSP7vv(j@`o+616f5Z zRBfHFEKA#SvclMY46NHDQAx=EegmZtNckCwh@(Gn6D>zT-|P~ zZ1}WeD2IqLvc2wU-TJe@lCd3&d(R*Jz}p7PLMY?Gt!pf$AO9r62{j}Tx7y0J1*7P=r`zxfJ7<>~SUeRlcY^fAH^L?B zsm^b(li zc=eQACpXFMCETH_eJY;l_YASM7b=ucQ7`JSauy!f;S~Qr;_^O;V<;E>Wl(Tb_G0uC z>>{JYU{Ml5RBxSS+6>FH^_g4`B~*XZXtffPN^T(?jCh8!i#X_L-1Ft4<)%>{;W*e@ zPj*Djk6f*jLvfCRI}WCJ0(HeYH=~n2+FOPh^e?4Z1@uTtB`-ojsQFz=RpzNWU)3CZ9I+ z@)Rbu^k2o4Dp2l}ROsFm>GY37acFBFleJaCd6raQWENmr?EKkaz|WSy=#S8xHT;CI z6qQZJiJ`kf}8TDx(i4*XYqOY&{ml0Y<309f^ zk~H)4%+78z(%iFxfYuGUPAc8(|L>+yG)7%`$Az_HuIj%haW?o~=S>!7-X-`eUCx+= z@H6nAW{1cwZXpOKR1sUiEyzj8Ly(~Wh53r*>1OZEOKj)zU!a3c#F^ui){cTfREuX2 zKi@p7jzQb8+-EWnG%UQYwIH;B`NL z!%;D-!{MkJ;y@B`lgbeZ_K3H>oc$r%mdD8}XaI~WP7SShqaJ9N0;c5joL5l?`7$Za zBEdBnufIsMQ1tAY!8;!Tn5SLz)^OMSd{I9kC_x-b_4-wvzqP<}w1g)RD|*@?Vi1{* z5e2Y2BQM(+toO5En3flnUr7KnTO%Sroe{+Sr!e?jEahoZnz}rNMm(ADqpi$6%eh$a F${wtcv&8@a diff --git a/public/assets/frontend/is-land.js b/public/assets/frontend/is-land.js new file mode 100644 index 00000000..435a13b9 --- /dev/null +++ b/public/assets/frontend/is-land.js @@ -0,0 +1,338 @@ +class Island extends HTMLElement { + static tagName = "is-land"; + static prefix = "is-land--"; + static attr = { + template: "data-island", + ready: "ready", + defer: "defer-hydration", + }; + + static onceCache = new Map(); + static onReady = new Map(); + + static fallback = { + ":not(is-land,:defined,[defer-hydration])": (readyPromise, node, prefix) => { + // remove from document to prevent web component init + let cloned = document.createElement(prefix + node.localName); + for(let attr of node.getAttributeNames()) { + cloned.setAttribute(attr, node.getAttribute(attr)); + } + + // Declarative Shadow DOM (with polyfill) + let shadowroot = node.shadowRoot; + if(!shadowroot) { + let tmpl = node.querySelector(":scope > template:is([shadowrootmode], [shadowroot])"); + if(tmpl) { + let mode = tmpl.getAttribute("shadowrootmode") || tmpl.getAttribute("shadowroot") || "closed"; + shadowroot = node.attachShadow({ mode }); // default is closed + shadowroot.appendChild(tmpl.content.cloneNode(true)); + } + } + + // Cheers to https://gist.github.com/developit/45c85e9be01e8c3f1a0ec073d600d01e + if(shadowroot) { + cloned.attachShadow({ mode: shadowroot.mode }).append(...shadowroot.childNodes); + } + + // Keep *same* child nodes to preserve state of children (e.g. details->summary) + cloned.append(...node.childNodes); + node.replaceWith(cloned); + + return readyPromise.then(() => { + // Restore original children and shadow DOM + if(cloned.shadowRoot) { + node.shadowRoot.append(...cloned.shadowRoot.childNodes); + } + node.append(...cloned.childNodes); + cloned.replaceWith(node); + }); + } + } + + constructor() { + super(); + + // Internal promises + this.ready = new Promise(resolve => { + this.readyResolve = resolve; + }); + } + + // any parents of `el` that are (with conditions) + static getParents(el, stopAt = false) { + let nodes = []; + while(el) { + if(el.matches && el.matches(Island.tagName)) { + if(stopAt && el === stopAt) { + break; + } + + if(Conditions.hasConditions(el)) { + nodes.push(el); + } + } + el = el.parentNode; + } + return nodes; + } + + static async ready(el, parents) { + if(!parents) { + parents = Island.getParents(el); + } + if(parents.length === 0) { + return; + } + let imports = await Promise.all(parents.map(p => p.wait())); + // return innermost module import + if(imports.length) { + return imports[0]; + } + } + + forceFallback() { + if(window.Island) { + Object.assign(Island.fallback, window.Island.fallback); + } + + for(let selector in Island.fallback) { + // Reverse here as a cheap way to get the deepest nodes first + let components = Array.from(this.querySelectorAll(selector)).reverse(); + + // with thanks to https://gist.github.com/cowboy/938767 + for(let node of components) { + if(!node.isConnected) { + continue; + } + + let parents = Island.getParents(node); + // must be in a leaf island (not nested deep) + if(parents.length === 1) { + let p = Island.ready(node, parents); + Island.fallback[selector](p, node, Island.prefix); + } + } + } + } + + wait() { + return this.ready; + } + + async connectedCallback() { + // Only use fallback content with loading conditions + if(Conditions.hasConditions(this)) { + // Keep fallback content without initializing the components + this.forceFallback(); + } + + await this.hydrate(); + } + + getTemplates() { + return this.querySelectorAll(`template[${Island.attr.template}]`); + } + + replaceTemplates(templates) { + // replace