Skip to content

Instantly share code, notes, and snippets.

View barneycarroll's full-sized avatar
🛠️
Working on Mithril type stuff

Barney Carroll barneycarroll

🛠️
Working on Mithril type stuff
View GitHub Profile
@barneycarroll
barneycarroll / changeTag.js
Created August 3, 2021 12:12
Replace an element with a new one that has a different tagName
export default function changeTag(original, tagName){
// Create a replacement tag of the desired type
const replacement = document.createElement(tagName)
// Grab all of the original's attributes, and pass them to the replacement
Array.prototype.forEach.call(original.attributes, ({name, value}) => {
replacement.setAttribute(name, value)
})
// Persist contents
@barneycarroll
barneycarroll / target.support.js
Last active July 13, 2021 15:42
Attempt at detecting CSS `:target` support
// Determine whether or not we need to run fallback code by testing for `:target` support.
var targetSupport = ( function targetSupport(){
var iframe = document.createElement( 'iframe' );
var body = document.getElementsByTagName( 'body' )[ 0 ];
var doc;
var outcome;
iframe.tabindex = -1;
iframe.style.display = 'none';
@barneycarroll
barneycarroll / animator.js
Last active June 11, 2021 05:06
A factory for decorating Mithril modules / views / elements with incoming and outgoing animations.
var animating = false;
// Define an animator consisting of optional incoming and outgoing animations.
// alwaysAnimate is false unless specified as true: false means an incoming animation will only trigger if an outgoing animation is also in progress.
// forcing dontClone to true means the outward animation will use the original element rather than a clone. This could improve performance by recycling elements, but can lead to trouble: clones have the advantage of being stripped of all event listeners.
function animator( incoming, outgoing, alwaysAnimate, dontClone ){
// The resulting animator can be applied to any number of components
return function animate( x, y, z ){
var config;
var parent;
@barneycarroll
barneycarroll / ui_io.js
Created May 23, 2021 20:57
User Interface Input / Output is a tool for observing all event triggers (UI input) & DOM mutations (UI output). Initialised with an optional callback function which receives all such entries in format {type: 'mutation' || 'event', time: performance.now(), data: originalEventOrMutationRecords}, the returned instance exposes {logs, next, disconne…
import muty from 'muty'
export default function ui_io(callback = Function.prototype){
const {addEventListener} = EventTarget.prototype
const promises = []
const listeners = []
const logs = []
function register(entry){
@barneycarroll
barneycarroll / eventListenerListener.js
Created May 12, 2021 11:39
Intercept & release / remove all event listeners. Partially as an easy way to make Mithril router single-SPA compliant.
const {addEventListener} = EventTarget.prototype
export default function EventListenerListener({
blocking = false,
removing = true,
visitor = Function.prototype,
} = {}){
if(this instanceof EventListenerListener){}
else return new EventListenerListener(...arguments)
const muties = new Set
class Muty extends MutationObserver {
observe(){
muties.add(this)
super.observe(...arguments)
}
disconnect(){
@barneycarroll
barneycarroll / README.md
Last active April 20, 2021 15:13
Run a Mithril application with Amok!

Amok is a live editing tool for javascript development. It is beyond awesome. It is the future of javascript development.

Mithril is a javascript framework for building brilliant applications.

This simple test case shows how we can use Amok's event handlers to trigger redraws as and when code is dynamically recompiled in the browser. It's a little taste of the awesome to come.

To use this demo:

  1. Install Amok
  2. You'll need Node
@barneycarroll
barneycarroll / mithril.steps.js
Created March 26, 2021 15:26
What if we could yield & await as discrete mechanisms for stepping through lifecycle?
// Async generators don't actually work this way: all yields implictly mandate asynchronous (non-synchronously-blocking) resolution under the hood; so in practice it's probably better to be honest and make this unambiguously wasteful & imprecise and have all steps as explicit awaits. 🙄
const KitchenSink = steps(async function * ($){
$.view(v =>
m('p.counter', $.attrs.value, '!')
)
yield $.create
style({
transition : 'none',
@barneycarroll
barneycarroll / life-cycle.js
Last active March 14, 2021 13:16
A generic lifecycle custom element for use in frameworks that don't implement lifecycle
customElements.define('life-cycle', class LifeCycle extends HTMLElement {
constructor(){
super()
}
connected(){}
connectedCallback(){
this.style.display = 'contents'
this.connected(...arguments)