| class ButtonInstall extends HTMLElement { | |
| init () { | |
| this.button = this.querySelector('button'); | |
| if (window.matchMedia('(display-mode: standalone)').matches) { | |
| this.button.remove(); | |
| return; | |
| } | |
| if (!navigator.install) { | |
| this.button.remove(); | |
| return; |
| @media (prefers-reduced-motion: no-preference) { | |
| @view-transition { | |
| navigation: auto; | |
| } | |
| } | |
| html { | |
| overflow-y: auto; | |
| scrollbar-gutter: stable; | |
| interpolate-size: allow-keywords; | |
| } |
| <?php | |
| /* | |
| Pass in a string: geocode("The Jolly Brewer, Brighton, East Sussex England") | |
| The output is an array with keys for "latitude", "longitude", and "zoom". | |
| */ | |
| function geocode($location, $provider = "mapquest") { | |
| $return = array(); |
| class EmbedMap extends HTMLElement { | |
| constructor () { | |
| super(); | |
| } | |
| loadScript(src, callback) { | |
| let script = document.createElement('script'); | |
| script.src = src; | |
| script.addEventListener('load', callback); | |
| document.querySelector('head').appendChild(script); | |
| } |
| <?php | |
| /* | |
| Pass in an array of data that includes the text of the post and an access token e.g. | |
| postToBluesky(array( | |
| 'text' => 'Hello World', | |
| 'accessToken' => getBlueskyToken() | |
| )); | |
| Here's the gist for getting getBlueskyToken(): | |
| https://gist.github.com/adactio/1a850920a0554a49f36daf79d776a440 |
| <?php | |
| /* | |
| Use this function whenever you need a token from Bluesky e.g. | |
| $my_token = getBlueskyToken(); | |
| */ | |
| function getBlueskyToken() { | |
| $url = "https://bsky.social/xrpc/com.atproto.server.createSession"; |
| <?php | |
| // Check that the request is coming from my site. | |
| if (!isset($_SERVER['HTTP_REFERER']) || !stristr(strtolower($_SERVER['HTTP_REFERER']), strtolower($_SERVER['SERVER_NAME']))) { | |
| http_response_code(403); | |
| exit; | |
| } | |
| // There has to be a URL provided in the query string. | |
| if (!isset($_GET['url'])) { |
| document.body.addEventListener('click', function(event) { | |
| var target = event.target.closest('a[href]'); | |
| if (!target) return; | |
| var href = encodeURIComponent(target.getAttribute('href')); | |
| if (!href.startsWith('http')) return | |
| if (href.includes('archive.org')) return | |
| var url = `/redirect.php?url=${href}`; | |
| if (target.closest('.h-entry') && target.closest('.h-entry').querySelector('time.dt-published[datetime]')) { | |
| var date = encodeURIComponent(target.closest('.h-entry').querySelector('time.dt-published').getAttribute('datetime')); | |
| url += `&date=${date}`; |
| <?php | |
| /* Pass a string of text into the function to convert @@ usernames. */ | |
| function autoLinkMastodonUsernames($string) { | |
| return preg_replace( | |
| '/@?\b([A-Za-zŽžÀ-ÿ0-9._%+-]+)@([A-Za-zŽžÀ-ÿ0-9.-]+\.[A-Za-zŽžÀ-ÿ]{2,})\b/i', | |
| '<a href="https://$2/@$1">$0</a>', | |
| $string |
| (function (win, doc) { | |
| 'use strict'; | |
| if (!doc.querySelectorAll || !win.Intl || !win.Intl.RelativeTimeFormat) { | |
| // doesn't cut the mustard. | |
| return; | |
| } | |
| var rtf = new Intl.RelativeTimeFormat('en', { | |
| localeMatcher: 'best fit', | |
| numeric: 'always', | |
| style: 'long' |