From 91fea14951acd432169a011766c7edf853498652 Mon Sep 17 00:00:00 2001 From: carson Date: Wed, 13 May 2020 17:58:06 -0700 Subject: [PATCH] small API and docs --- TODO.md | 12 - dist/kutty.js | 202 ++++++++++++----- dist/kutty.min.js | 2 +- dist/kutty.min.js.gz | Bin 5518 -> 5682 bytes src/kutty.js | 214 ++++++++++++------ www/_includes/layout.njk | 3 + www/index.md | 2 +- .../2020-5-15-kutty-0.0.1-is-released.md | 40 ++++ www/talk.md | 17 ++ 9 files changed, 342 insertions(+), 150 deletions(-) create mode 100644 www/posts/2020-5-15-kutty-0.0.1-is-released.md create mode 100644 www/talk.md diff --git a/TODO.md b/TODO.md index e09a3b68..c0a55110 100644 --- a/TODO.md +++ b/TODO.md @@ -6,9 +6,6 @@ ## Launch TODOS -* Testing - * events - * X-KT-Trigger response header * Blog Post * Move to development branch * Publish 0.0.1 @@ -30,17 +27,8 @@ * ctrl-click on boosted anchors let's tab open normally * `kutty-on="myEvent: ...""` attribute for handling custom events -* kutty javascript API - * find - * findAll - * closest - * remove - * sequence(op1, op2) - * add/remove/toggleClass - * trigger * `kutty-requests` class on body * local references (e.g. kt-get="#foo") -* polling cancellation API 205 code * focus recapture * Move to weakmap for kutty node info? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap * Scroll handler use https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API if available? diff --git a/dist/kutty.js b/dist/kutty.js index e628ec29..c8b00310 100644 --- a/dist/kutty.js +++ b/dist/kutty.js @@ -63,11 +63,6 @@ var kutty = kutty || (function () { return matchesFunction && matchesFunction.call(elt, selector); } - function closest(elt, selector) { - do if (elt == null || matches(elt, selector)) return elt; - while (elt = elt && parentElt(elt)); - } - function getStartTag(str) { var tagMatcher = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i var match = tagMatcher.exec( str ); @@ -163,6 +158,119 @@ var kutty = kutty || (function () { sheet.insertRule(rule, sheet.cssRules.length); } + //========================================================================================== + // public API + //========================================================================================== + + function internalEval(str){ + return eval(str); + } + + function onLoadHelper(callback) { + kutty.on("load.kutty", function(evt) { + callback(evt.detail.elt); + }); + } + + function logAll(){ + kutty.logger = function(elt, event, data) { + if(console) { + console.log(event, elt, data); + } + } + } + + function find(eltOrSelector, selector) { + if (selector) { + eltOrSelector.querySelector(eltOrSelector); + } else { + getDocument().body.querySelector(eltOrSelector); + } + } + + function findAll(eltOrSelector, selector) { + if (selector) { + eltOrSelector.querySelectorAll(eltOrSelector); + } else { + getDocument().body.querySelectorAll(eltOrSelector); + } + } + + function removeElement(elt, delay) { + if (delay) { + setTimeout(function(){removeElement(elt);}, delay) + } else { + elt.parentElement.removeChild(elt); + } + } + + function addClassToElement(elt, clazz, delay) { + if (delay) { + setTimeout(function(){addClassToElement(elt, clazz);}, delay) + } else { + elt.classList.add(clazz); + } + } + + function removeClassFromElement(elt, clazz) { + if (delay) { + setTimeout(function(){removeClassFromElement(elt, clazz);}, delay) + } else { + elt.classList.remove(clazz); + } + } + + function toggleClassOnElement(elt, clazz) { + elt.classList.toggle(clazz); + } + + function takeClassForElement(elt, clazz) { + forEach(elt.parent.children, function(child){ + removeClassFromElement(child, clazz); + }) + addClassToElement(elt, clazz); + } + + function closest(elt, selector) { + do if (elt == null || matches(elt, selector)) return elt; + while (elt = elt && parentElt(elt)); + } + + function processEventArgs(arg1, arg2, arg3) { + if (isFunction(arg2)) { + return { + target: getDocument().body, + event: arg1, + listener: arg2 + } + } else { + return { + target: arg1, + event: arg2, + listener: arg3 + } + } + + } + + function addKuttyEventListener(arg1, arg2, arg3) { + var eventArgs = processEventArgs(arg1, arg2, arg3); + ready(function(){ + eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener); + }) + return eventArgs.listener; + } + + function removeKuttyEventListener(arg1, arg2, arg3) { + var eventArgs = processEventArgs(arg1, arg2, arg3); + ready(function(){ + eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener); + }) + return eventArgs.listener; + } + + + //==================================================================== // Node processing //==================================================================== @@ -208,7 +316,7 @@ var kutty = kutty || (function () { settleTasks = settleTasks.concat(swapOuterHTML(target, fragment)); } else { child.parentNode.removeChild(child); - triggerEvent(getDocument().body, "oobErrorNoTarget.kutty", {content: child}) + triggerErrorEvent(getDocument().body, "oobErrorNoTarget.kutty", {content: child}) } } }); @@ -535,7 +643,7 @@ var kutty = kutty || (function () { triggerEvent(elt, "initSSE.kutty", detail); var source = new EventSource(sseSrc, detail.config); source.onerror = function (e) { - triggerEvent(elt, "sseError.kutty", {error:e, source:source}); + triggerErrorEvent(elt, "sseError.kutty", {error:e, source:source}); maybeCloseSSESource(elt); }; getInternalData(elt).sseSource = source; @@ -557,7 +665,7 @@ var kutty = kutty || (function () { }; sseSource.sseSource.addEventListener(sseEventName, sseListener); } else { - triggerEvent(elt, "noSSESourceError.kutty") + triggerErrorEvent(elt, "noSSESourceError.kutty") } } @@ -651,42 +759,21 @@ var kutty = kutty || (function () { return evt; } + function triggerErrorEvent(elt, eventName, detail) { + triggerEvent(elt, eventName, Object.assign({isError:true}, details)); + } + function triggerEvent(elt, eventName, detail) { detail["elt"] = elt; var event = makeEvent(eventName, detail); if (kutty.logger) { kutty.logger(elt, eventName, detail); - if (eventName.indexOf("Error") > 0) { + if (detail.isError) { sendError(elt, eventName, detail); } } var eventResult = elt.dispatchEvent(event); - var allResult = elt.dispatchEvent(makeEvent("all.kutty", {originalDetail:detail, originalEvent: event})); - return eventResult && allResult; - } - - function addKuttyEventListener(arg1, arg2, arg3) { - var target, event, listener; - if (isFunction(arg1)) { - ready(function(){ - target = getDocument().body; - event = "all.kutty"; - listener = arg1; - target.addEventListener(event, listener); - }) - } else if (isFunction(arg2)) { - ready(function () { - target = getDocument().body; - event = arg1; - listener = arg2; - target.addEventListener(event, listener); - }) - } else { - target = arg1; - event = arg2; - listener = arg3; - target.addEventListener(event, listener); - } + return eventResult; } //==================================================================== @@ -756,7 +843,7 @@ var kutty = kutty || (function () { settleImmediately(swapInnerHTML(getHistoryElement(), fragment)); currentPathForHistory = path; } else { - triggerEvent(getDocument().body, "historyCacheMissLoadError.kutty", details); + triggerErrorEvent(getDocument().body, "historyCacheMissLoadError.kutty", details); } }; request.send(); @@ -992,7 +1079,7 @@ var kutty = kutty || (function () { function issueAjaxRequest(elt, verb, path, eventTarget) { var target = getTarget(elt); if (target == null) { - triggerEvent(elt, 'targetError.kutty', {target: getRawAttribute(elt, "kt-target")}); + triggerErrorEvent(elt, 'targetError.kutty', {target: getRawAttribute(elt, "kt-target")}); return; } var eltData = getInternalData(elt); @@ -1110,7 +1197,7 @@ var kutty = kutty || (function () { doSettle(); } } catch (e) { - triggerEvent(elt, 'swapError.kutty', eventDetail); + triggerErrorEvent(elt, 'swapError.kutty', eventDetail); throw e; } }; @@ -1122,11 +1209,11 @@ var kutty = kutty || (function () { } } } else { - triggerEvent(elt, 'responseError.kutty', eventDetail); + triggerErrorEvent(elt, 'responseError.kutty', eventDetail); } } catch (e) { eventDetail['exception'] = e; - triggerEvent(elt, 'onLoadError.kutty', eventDetail); + triggerErrorEvent(elt, 'onLoadError.kutty', eventDetail); throw e; } finally { removeRequestIndicatorClasses(elt); @@ -1135,7 +1222,8 @@ var kutty = kutty || (function () { } } xhr.onerror = function () { - removeRequestIndicatorClasses(elt);triggerEvent(elt, 'sendError.kutty', eventDetail); + removeRequestIndicatorClasses(elt); + triggerErrorEvent(elt, 'sendError.kutty', eventDetail); endRequestLock(); } if(!triggerEvent(elt, 'beforeRequest.kutty', eventDetail)) return endRequestLock(); @@ -1179,29 +1267,21 @@ var kutty = kutty || (function () { }; }) - function internalEval(str){ - return eval(str); - } - - function onLoadHelper(callback) { - kutty.on("load.kutty", function(evt) { - callback(evt.detail.elt); - }); - } - - function logAll(){ - kutty.logger = function(elt, event, data) { - if(console) { - console.log(event, elt, data); - } - } - } - // Public API return { - processElement: processNode, - on: addKuttyEventListener, onLoad: onLoadHelper, + process: processNode, + on: addKuttyEventListener, + off: removeKuttyEventListener, + trigger : triggerEvent, + find : find, + findAll : findAll, + closest : closest, + remove : removeElement, + addClass : addClassToElement, + removeClass : removeClassFromElement, + toggleClass : toggleClassOnElement, + takeClass : takeClassForElement, logAll : logAll, logger : null, config : { diff --git a/dist/kutty.min.js b/dist/kutty.min.js index 1368f357..c79d3e7b 100644 --- a/dist/kutty.min.js +++ b/dist/kutty.min.js @@ -1 +1 @@ -var kutty=kutty||function(){"use strict";var e=["get","post","put","delete","patch"];function k(e){if(e==="null"||e==="false"||e===""){return null}else if(e.lastIndexOf("ms")===e.length-2){return parseFloat(e.substr(0,e.length-2))}else if(e.lastIndexOf("s")===e.length-1){return parseFloat(e.substr(0,e.length-1))*1e3}else{return parseFloat(e)}}function b(e,t){return e.getAttribute&&e.getAttribute(t)}function u(e,t){return b(e,t)||b(e,"data-"+t)}function n(e){return e.parentElement}function o(){return document}function l(e,t){if(t(e)){return e}else if(n(e)){return l(n(e),t)}else{return null}}function S(e,t){var r=null;l(e,function(e){return r=b(e,t)});return r}function s(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function a(e,t){do{if(e==null||s(e,t))return e}while(e=e&&n(e))}function r(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function i(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}return i}function f(e){var t=r(e);switch(t){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return i(""+e+"
",1);case"col":return i(""+e+"
",2);case"tr":return i(""+e+"
",2);case"td":case"th":return i(""+e+"
",3);default:return i(e,0)}}function t(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function c(e){return t(e,"Function")}function v(e){return t(e,"Object")}function w(e){var t="kutty-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function E(e,t){if(e){for(var r=0;r=0}function y(e){return o().body.contains(e)}function g(e,t){return e.concat(t)}function h(e){return e.split(/\s+/)}function p(e){var t=o().styleSheets[0];t.insertRule(e,t.cssRules.length)}function T(e){var t=l(e,function(e){return b(e,"kt-target")!==null});if(t){var r=b(t,"kt-target");if(r==="this"){return t}else{return o().querySelector(r)}}else{var n=w(e);if(n.boosted){return o().body}else{return e}}}function m(t,r){E(t.attributes,function(e){if(!r.hasAttribute(e.name)){t.removeAttribute(e.name)}});E(r.attributes,function(e){t.setAttribute(e.name,e.value)})}function O(e){var n=[];E(e.children,function(e){if(u(e,"kt-swap-oob")==="true"){var t=o().getElementById(e.id);if(t){var r=o().createDocumentFragment();r.appendChild(e);n=n.concat(N(t,r))}else{e.parentNode.removeChild(e);re(o().body,"oobErrorNoTarget.kutty",{content:e})}}});return n}function L(n,e){var i=[];E(e.querySelectorAll("[id]"),function(e){var t=n.querySelector(e.tagName+"[id="+e.id+"]");if(t){var r=e.cloneNode();m(e,t);i.push(function(){m(e,r)})}});return i}function C(e,t,r){var n=L(e,r);while(r.childNodes.length>0){var i=r.firstChild;e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE){re(i,"load.kutty",{});$(i)}}return n}function N(e,t){if(e.tagName==="BODY"){return M(e,t)}else{var r=C(n(e),e,t);n(e).removeChild(e);return r}}function q(e,t){return C(e,e.firstChild,t)}function x(e,t){return C(n(e),e,t)}function A(e,t){return C(e,null,t)}function D(e,t){return C(n(e),e.nextSibling,t)}function M(e,t){var r=e.firstChild;var n=C(e,r,t);if(r){while(r.nextSibling){e.removeChild(r.nextSibling)}e.removeChild(r)}return n}function R(e,t){var r=S(e,"kt-select");if(r){var n=o().createDocumentFragment();E(t.querySelectorAll(r),function(e){n.appendChild(e)});t=n}return t}function X(e,t,r,n){var i=f(n);if(i){var a=O(i);i=R(r,i);switch(e){case"outerHTML":return g(a,N(t,i));case"afterbegin":return g(a,q(t,i));case"beforebegin":return g(a,x(t,i));case"beforeend":return g(a,A(t,i));case"afterend":return g(a,D(t,i));default:return g(a,M(t,i))}}}function H(e,t){if(t){if(t.indexOf("{")===0){var r=JSON.parse(t);for(var n in r){if(r.hasOwnProperty(n)){var i=r[n];if(!v(i)){i={value:i}}re(e,n,i)}}}else{re(e,t,[])}}}function I(e){var t={trigger:"click"};var r=u(e,"kt-trigger");if(r){var n=h(r);if(n.length>0){var i=n[0];if(i==="every"){t.pollInterval=k(n[1])}else if(i.indexOf("sse:")===0){t.sseEvent=i.substr(4)}else{t["trigger"]=i;for(var a=1;a1){var r=t[0];var n=t[1].trim();var i;var a;if(n.indexOf(":")>0){var o=n.split(":");i=o[0];a=k(o[1])}else{i=n;a=100}return{operation:r,cssClass:i,delay:a}}else{return null}}function K(i,e){E(e.split("&"),function(e){var n=0;E(e.split(","),function(e){var t=e.trim();var r=F(t);if(r){if(r.operation==="toggle"){setTimeout(function(){setInterval(function(){i.classList[r.operation].call(i.classList,r.cssClass)},r.delay)},n);n=n+r.delay}else{n=n+r.delay;setTimeout(function(){i.classList[r.operation].call(i.classList,r.cssClass)},n)}}})})}function P(e){w(e).cancelled=true}function j(e,t,r,n){var i=w(e);i.timeout=setTimeout(function(){if(y(e)&&i.cancelled!==true){Le(e,t,r);j(e,t,u(e,"kt-"+t),n)}},n)}function J(e){return location.hostname===e.hostname&&b(e,"href")&&!b(e,"href").startsWith("#")}function U(e,t,r){if(e.tagName==="A"&&J(e)||e.tagName==="FORM"){t.boosted=true;var n,i;if(e.tagName==="A"){n="get";i=b(e,"href")}else{var a=b(e,"method");n=a?a.toLowerCase():"get";i=b(e,"action")}B(e,n,i,t,r,true)}}function z(e){return e.tagName==="FORM"||s(e,'input[type="submit"], button')&&a(e,"form")!==null||e.tagName==="A"&&e.href&&e.href.indexOf("#")!==0}function B(i,a,o,e,u,l){var t=function(e){if(l||z(i))e.preventDefault();var t=w(e);var r=w(i);if(!t.handled){t.handled=true;if(u.once){if(r.triggeredOnce){return}else{r.triggeredOnce=true}}if(u.changed){if(r.lastValue===i.value){return}else{r.lastValue=i.value}}if(r.delayed){clearTimeout(r.delayed)}var n=function(){Le(i,a,o,e.target)};if(u.delay){r.delayed=setTimeout(n,u.delay)}else{n()}}};e.trigger=u.trigger;e.eventListener=t;i.addEventListener(u.trigger,t)}function V(){if(!window["kuttyScrollHandler"]){var e=function(){E(o().querySelectorAll("[kt-trigger='revealed']"),function(e){G(e)})};window["kuttyScrollHandler"]=e;window.addEventListener("scroll",e)}}function G(e){var t=w(e);if(!t.revealed&&d(e)){t.revealed=true;Le(e,t.verb,t.path)}}function Y(e){if(!y(e)){e.sseSource.close();return true}}function _(t,e){var r={config:{withCredentials:true}};re(t,"initSSE.kutty",r);var n=new EventSource(e,r.config);n.onerror=function(e){re(t,"sseError.kutty",{error:e,source:n});Y(t)};w(t).sseSource=n}function W(e,t,r,n){var i=l(e,function(e){return e.sseSource});if(i){var a=function(){if(!Y(i)){if(y(e)){Le(e,t,r)}else{i.sseSource.removeEventListener(n,a)}}};i.sseSource.addEventListener(n,a)}else{re(e,"noSSESourceError.kutty")}}function Q(e,t,r,n,i){var a=function(){if(!n.loaded){n.loaded=true;Le(e,t,r)}};if(i){setTimeout(a,i)}else{a()}}function Z(r,n,i){var a=false;E(e,function(e){var t=u(r,"kt-"+e);if(t){a=true;n.path=t;n.verb=e;if(i.sseEvent){W(r,e,t,i.sseEvent)}else if(i.trigger==="revealed"){V();G(r)}else if(i.trigger==="load"){Q(r,e,t,n,i.delay)}else if(i.pollInterval){n.polling=true;j(r,e,t,i.pollInterval)}else{B(r,e,t,n,i)}}});return a}function $(e){var t=w(e);if(!t.processed){t.processed=true;var r=I(e);var n=Z(e,t,r);if(!n&&S(e,"kt-boost")==="true"){U(e,t,r)}var i=u(e,"kt-sse-source");if(i){_(e,i)}var a=u(e,"kt-classes");if(a){K(e,a)}}if(e.children){E(e.children,function(e){$(e)})}}function ee(e,t,r){var n=S(e,"kt-error-url");if(n){var i=new XMLHttpRequest;i.open("POST",n);i.setRequestHeader("Content-Type","application/json;charset=UTF-8");i.send(JSON.stringify({elt:e.id,event:t,detail:r}))}}function te(e,t){var r;if(window.CustomEvent&&typeof window.CustomEvent==="function"){r=new CustomEvent(e,{bubbles:true,cancelable:true,detail:t})}else{r=o().createEvent("CustomEvent");r.initCustomEvent(e,true,true,t)}return r}function re(e,t,r){r["elt"]=e;var n=te(t,r);if(kutty.logger){kutty.logger(e,t,r);if(t.indexOf("Error")>0){ee(e,t,r)}}var i=e.dispatchEvent(n);var a=e.dispatchEvent(te("all.kutty",{originalDetail:r,originalEvent:n}));return i&&a}function ne(e,t,r){var n,i,a;if(c(e)){Ce(function(){n=o().body;i="all.kutty";a=e;n.addEventListener(i,a)})}else if(c(t)){Ce(function(){n=o().body;i=e;a=t;n.addEventListener(i,a)})}else{n=e;i=t;a=r;n.addEventListener(i,a)}}var ie=null;function ae(){var e=o().querySelector("[kt-history-elt]");return e||o().body}function oe(e,t,r,n){var i=JSON.parse(localStorage.getItem("kutty-history-cache"))||[];for(var a=0;akutty.config.historyCacheSize){i.shift()}localStorage.setItem("kutty-history-cache",JSON.stringify(i))}function ue(e){var t=JSON.parse(localStorage.getItem("kutty-history-cache"))||[];for(var r=0;r=200&&this.status<400){re(o().body,"historyCacheMissLoad.kutty",r);var e=f(this.response);e=e.querySelector("[kt-history-elt]")||e;fe(M(ae(),e));ie=t}else{re(o().body,"historyCacheMissLoadError.kutty",r)}};e.send()}function ve(e){le(ie);e=e||location.pathname+location.search;re(o().body,"historyRestore.kutty",{path:e});var t=ue(e);if(t){fe(M(ae(),f(t.content)));document.title=t.title;window.scrollTo(0,t.scroll);ie=e}else{ce(e)}}function de(e){return S(e,"kt-push-url")==="true"||e.tagName==="A"&&w(e).boosted}function ye(e){he(e,"add")}function ge(e){he(e,"remove")}function he(e,t){var r=S(e,"kt-indicator");if(r){var n=o().querySelectorAll(r)}else{n=[e]}E(n,function(e){e.classList[t].call(e.classList,"kutty-request")})}function pe(e,t){for(var r=0;r0){r["swapStyle"]=n[0];for(var i=1;i=200&&this.status<400){if(this.status===286){P(o)}if(this.status!==204){if(!re(o,"beforeSwap.kutty",m))return;var i=this.response;if(n){le()}var a=Oe(o);u.classList.add("kutty-swapping");var e=function(){try{var e=X(a.swapStyle,u,o,i);u.classList.remove("kutty-swapping");u.classList.add("kutty-settling");re(o,"afterSwap.kutty",m);var t=function(){E(e,function(e){e.call()});u.classList.remove("kutty-settling");if(n){se(r||g)}re(o,"afterSettle.kutty",m)};if(a.settleDelay>0){setTimeout(t,a.settleDelay)}else{t()}}catch(e){re(o,"swapError.kutty",m);throw e}};if(a.swapDelay>0){setTimeout(e,k(a.swapDelay))}else{e()}}}else{re(o,"responseError.kutty",m)}}catch(e){m["exception"]=e;re(o,"onLoadError.kutty",m);throw e}finally{ge(o);l();re(o,"afterOnLoad.kutty",m)}};f.onerror=function(){ge(o);re(o,"sendError.kutty",m);l()};if(!re(o,"beforeRequest.kutty",m))return l();ye(o);f.send(e==="get"?null:we(d))}function Ce(e){if(o().readyState!=="loading"){e()}else{o().addEventListener("DOMContentLoaded",e)}}p(".kutty-indicator{opacity:0;transition: opacity 200ms ease-in;}");p(".kutty-request .kutty-indicator{opacity:1}");p(".kutty-request.kutty-indicator{opacity:1}");function Ne(){var e=o().querySelector('meta[name="kutty-config"]');if(e){var t=JSON.parse(e.content);kutty.config=Object.assign(kutty.config,t)}}Ce(function(){Ne();var e=o().body;$(e);re(e,"load.kutty",{});window.onpopstate=function(){ve()}});function qe(e){return eval(e)}function xe(t){kutty.on("load.kutty",function(e){t(e.detail.elt)})}function Ae(){kutty.logger=function(e,t,r){if(console){console.log(t,e,r)}}}return{processElement:$,on:ne,onLoad:xe,logAll:Ae,logger:null,config:{historyEnabled:true,historyCacheSize:10,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:100},version:"0.0.1",_:qe}}(); \ No newline at end of file +var kutty=kutty||function(){"use strict";var e=["get","post","put","delete","patch"];function k(e){if(e==="null"||e==="false"||e===""){return null}else if(e.lastIndexOf("ms")===e.length-2){return parseFloat(e.substr(0,e.length-2))}else if(e.lastIndexOf("s")===e.length-1){return parseFloat(e.substr(0,e.length-1))*1e3}else{return parseFloat(e)}}function b(e,t){return e.getAttribute&&e.getAttribute(t)}function u(e,t){return b(e,t)||b(e,"data-"+t)}function n(e){return e.parentElement}function a(){return document}function o(e,t){if(t(e)){return e}else if(n(e)){return o(n(e),t)}else{return null}}function S(e,t){var r=null;o(e,function(e){return r=b(e,t)});return r}function l(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function r(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function i(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}return i}function s(e){var t=r(e);switch(t){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return i(""+e+"
",1);case"col":return i(""+e+"
",2);case"tr":return i(""+e+"
",2);case"td":case"th":return i(""+e+"
",3);default:return i(e,0)}}function t(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function f(e){return t(e,"Function")}function c(e){return t(e,"Object")}function w(e){var t="kutty-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function E(e,t){if(e){for(var r=0;r=0}function v(e){return a().body.contains(e)}function y(e,t){return e.concat(t)}function g(e){return e.split(/\s+/)}function h(e){var t=a().styleSheets[0];t.insertRule(e,t.cssRules.length)}function p(e){return eval(e)}function m(t){kutty.on("load.kutty",function(e){t(e.detail.elt)})}function T(){kutty.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function C(e,t){if(t){e.querySelector(e)}else{a().body.querySelector(e)}}function L(e,t){if(t){e.querySelectorAll(e)}else{a().body.querySelectorAll(e)}}function O(e,t){if(t){setTimeout(function(){O(e)},t)}else{e.parentElement.removeChild(e)}}function q(e,t,r){if(r){setTimeout(function(){q(e,t)},r)}else{e.classList.add(t)}}function N(e,t){if(delay){setTimeout(function(){N(e,t)},delay)}else{e.classList.remove(t)}}function A(e,t){e.classList.toggle(t)}function x(e,t){E(e.parent.children,function(e){N(e,t)});q(e,t)}function D(e,t){do{if(e==null||l(e,t))return e}while(e=e&&n(e))}function M(e,t,r){if(f(t)){return{target:a().body,event:e,listener:t}}else{return{target:e,event:t,listener:r}}}function R(e,t,r){var n=M(e,t,r);Pe(function(){n.target.addEventListener(n.event,n.listener)});return n.listener}function X(e,t,r){var n=M(e,t,r);Pe(function(){n.target.addEventListener(n.event,n.listener)});return n.listener}function H(e){var t=o(e,function(e){return b(e,"kt-target")!==null});if(t){var r=b(t,"kt-target");if(r==="this"){return t}else{return a().querySelector(r)}}else{var n=w(e);if(n.boosted){return a().body}else{return e}}}function I(t,r){E(t.attributes,function(e){if(!r.hasAttribute(e.name)){t.removeAttribute(e.name)}});E(r.attributes,function(e){t.setAttribute(e.name,e.value)})}function F(e){var n=[];E(e.children,function(e){if(u(e,"kt-swap-oob")==="true"){var t=a().getElementById(e.id);if(t){var r=a().createDocumentFragment();r.appendChild(e);n=n.concat(j(t,r))}else{e.parentNode.removeChild(e);ge(a().body,"oobErrorNoTarget.kutty",{content:e})}}});return n}function K(n,e){var i=[];E(e.querySelectorAll("[id]"),function(e){var t=n.querySelector(e.tagName+"[id="+e.id+"]");if(t){var r=e.cloneNode();I(e,t);i.push(function(){I(e,r)})}});return i}function P(e,t,r){var n=K(e,r);while(r.childNodes.length>0){var i=r.firstChild;e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE){he(i,"load.kutty",{});de(i)}}return n}function j(e,t){if(e.tagName==="BODY"){return V(e,t)}else{var r=P(n(e),e,t);n(e).removeChild(e);return r}}function J(e,t){return P(e,e.firstChild,t)}function U(e,t){return P(n(e),e,t)}function z(e,t){return P(e,null,t)}function B(e,t){return P(n(e),e.nextSibling,t)}function V(e,t){var r=e.firstChild;var n=P(e,r,t);if(r){while(r.nextSibling){e.removeChild(r.nextSibling)}e.removeChild(r)}return n}function G(e,t){var r=S(e,"kt-select");if(r){var n=a().createDocumentFragment();E(t.querySelectorAll(r),function(e){n.appendChild(e)});t=n}return t}function Y(e,t,r,n){var i=s(n);if(i){var a=F(i);i=G(r,i);switch(e){case"outerHTML":return y(a,j(t,i));case"afterbegin":return y(a,J(t,i));case"beforebegin":return y(a,U(t,i));case"beforeend":return y(a,z(t,i));case"afterend":return y(a,B(t,i));default:return y(a,V(t,i))}}}function _(e,t){if(t){if(t.indexOf("{")===0){var r=JSON.parse(t);for(var n in r){if(r.hasOwnProperty(n)){var i=r[n];if(!c(i)){i={value:i}}he(e,n,i)}}}else{he(e,t,[])}}}function W(e){var t={trigger:"click"};var r=u(e,"kt-trigger");if(r){var n=g(r);if(n.length>0){var i=n[0];if(i==="every"){t.pollInterval=k(n[1])}else if(i.indexOf("sse:")===0){t.sseEvent=i.substr(4)}else{t["trigger"]=i;for(var a=1;a1){var r=t[0];var n=t[1].trim();var i;var a;if(n.indexOf(":")>0){var o=n.split(":");i=o[0];a=k(o[1])}else{i=n;a=100}return{operation:r,cssClass:i,delay:a}}else{return null}}function Z(i,e){E(e.split("&"),function(e){var n=0;E(e.split(","),function(e){var t=e.trim();var r=Q(t);if(r){if(r.operation==="toggle"){setTimeout(function(){setInterval(function(){i.classList[r.operation].call(i.classList,r.cssClass)},r.delay)},n);n=n+r.delay}else{n=n+r.delay;setTimeout(function(){i.classList[r.operation].call(i.classList,r.cssClass)},n)}}})})}function $(e){w(e).cancelled=true}function ee(e,t,r,n){var i=w(e);i.timeout=setTimeout(function(){if(v(e)&&i.cancelled!==true){Ke(e,t,r);ee(e,t,u(e,"kt-"+t),n)}},n)}function te(e){return location.hostname===e.hostname&&b(e,"href")&&!b(e,"href").startsWith("#")}function re(e,t,r){if(e.tagName==="A"&&te(e)||e.tagName==="FORM"){t.boosted=true;var n,i;if(e.tagName==="A"){n="get";i=b(e,"href")}else{var a=b(e,"method");n=a?a.toLowerCase():"get";i=b(e,"action")}ie(e,n,i,t,r,true)}}function ne(e){return e.tagName==="FORM"||l(e,'input[type="submit"], button')&&D(e,"form")!==null||e.tagName==="A"&&e.href&&e.href.indexOf("#")!==0}function ie(i,a,o,e,u,l){var t=function(e){if(l||ne(i))e.preventDefault();var t=w(e);var r=w(i);if(!t.handled){t.handled=true;if(u.once){if(r.triggeredOnce){return}else{r.triggeredOnce=true}}if(u.changed){if(r.lastValue===i.value){return}else{r.lastValue=i.value}}if(r.delayed){clearTimeout(r.delayed)}var n=function(){Ke(i,a,o,e.target)};if(u.delay){r.delayed=setTimeout(n,u.delay)}else{n()}}};e.trigger=u.trigger;e.eventListener=t;i.addEventListener(u.trigger,t)}function ae(){if(!window["kuttyScrollHandler"]){var e=function(){E(a().querySelectorAll("[kt-trigger='revealed']"),function(e){oe(e)})};window["kuttyScrollHandler"]=e;window.addEventListener("scroll",e)}}function oe(e){var t=w(e);if(!t.revealed&&d(e)){t.revealed=true;Ke(e,t.verb,t.path)}}function ue(e){if(!v(e)){e.sseSource.close();return true}}function le(t,e){var r={config:{withCredentials:true}};he(t,"initSSE.kutty",r);var n=new EventSource(e,r.config);n.onerror=function(e){ge(t,"sseError.kutty",{error:e,source:n});ue(t)};w(t).sseSource=n}function se(e,t,r,n){var i=o(e,function(e){return e.sseSource});if(i){var a=function(){if(!ue(i)){if(v(e)){Ke(e,t,r)}else{i.sseSource.removeEventListener(n,a)}}};i.sseSource.addEventListener(n,a)}else{ge(e,"noSSESourceError.kutty")}}function fe(e,t,r,n,i){var a=function(){if(!n.loaded){n.loaded=true;Ke(e,t,r)}};if(i){setTimeout(a,i)}else{a()}}function ce(r,n,i){var a=false;E(e,function(e){var t=u(r,"kt-"+e);if(t){a=true;n.path=t;n.verb=e;if(i.sseEvent){se(r,e,t,i.sseEvent)}else if(i.trigger==="revealed"){ae();oe(r)}else if(i.trigger==="load"){fe(r,e,t,n,i.delay)}else if(i.pollInterval){n.polling=true;ee(r,e,t,i.pollInterval)}else{ie(r,e,t,n,i)}}});return a}function de(e){var t=w(e);if(!t.processed){t.processed=true;var r=W(e);var n=ce(e,t,r);if(!n&&S(e,"kt-boost")==="true"){re(e,t,r)}var i=u(e,"kt-sse-source");if(i){le(e,i)}var a=u(e,"kt-classes");if(a){Z(e,a)}}if(e.children){E(e.children,function(e){de(e)})}}function ve(e,t,r){var n=S(e,"kt-error-url");if(n){var i=new XMLHttpRequest;i.open("POST",n);i.setRequestHeader("Content-Type","application/json;charset=UTF-8");i.send(JSON.stringify({elt:e.id,event:t,detail:r}))}}function ye(e,t){var r;if(window.CustomEvent&&typeof window.CustomEvent==="function"){r=new CustomEvent(e,{bubbles:true,cancelable:true,detail:t})}else{r=a().createEvent("CustomEvent");r.initCustomEvent(e,true,true,t)}return r}function ge(e,t,r){he(e,t,Object.assign({isError:true},details))}function he(e,t,r){r["elt"]=e;var n=ye(t,r);if(kutty.logger){kutty.logger(e,t,r);if(r.isError){ve(e,t,r)}}var i=e.dispatchEvent(n);return i}var pe=null;function me(){var e=a().querySelector("[kt-history-elt]");return e||a().body}function ke(e,t,r,n){var i=JSON.parse(localStorage.getItem("kutty-history-cache"))||[];for(var a=0;akutty.config.historyCacheSize){i.shift()}localStorage.setItem("kutty-history-cache",JSON.stringify(i))}function be(e){var t=JSON.parse(localStorage.getItem("kutty-history-cache"))||[];for(var r=0;r=200&&this.status<400){he(a().body,"historyCacheMissLoad.kutty",r);var e=s(this.response);e=e.querySelector("[kt-history-elt]")||e;Ee(V(me(),e));pe=t}else{ge(a().body,"historyCacheMissLoadError.kutty",r)}};e.send()}function Ce(e){Se(pe);e=e||location.pathname+location.search;he(a().body,"historyRestore.kutty",{path:e});var t=be(e);if(t){Ee(V(me(),s(t.content)));document.title=t.title;window.scrollTo(0,t.scroll);pe=e}else{Te(e)}}function Le(e){return S(e,"kt-push-url")==="true"||e.tagName==="A"&&w(e).boosted}function Oe(e){Ne(e,"add")}function qe(e){Ne(e,"remove")}function Ne(e,t){var r=S(e,"kt-indicator");if(r){var n=a().querySelectorAll(r)}else{n=[e]}E(n,function(e){e.classList[t].call(e.classList,"kutty-request")})}function Ae(e,t){for(var r=0;r0){r["swapStyle"]=n[0];for(var i=1;i=200&&this.status<400){if(this.status===286){$(o)}if(this.status!==204){if(!he(o,"beforeSwap.kutty",m))return;var i=this.response;if(n){Se()}var a=Fe(o);u.classList.add("kutty-swapping");var e=function(){try{var e=Y(a.swapStyle,u,o,i);u.classList.remove("kutty-swapping");u.classList.add("kutty-settling");he(o,"afterSwap.kutty",m);var t=function(){E(e,function(e){e.call()});u.classList.remove("kutty-settling");if(n){we(r||g)}he(o,"afterSettle.kutty",m)};if(a.settleDelay>0){setTimeout(t,a.settleDelay)}else{t()}}catch(e){ge(o,"swapError.kutty",m);throw e}};if(a.swapDelay>0){setTimeout(e,k(a.swapDelay))}else{e()}}}else{ge(o,"responseError.kutty",m)}}catch(e){m["exception"]=e;ge(o,"onLoadError.kutty",m);throw e}finally{qe(o);l();he(o,"afterOnLoad.kutty",m)}};f.onerror=function(){qe(o);ge(o,"sendError.kutty",m);l()};if(!he(o,"beforeRequest.kutty",m))return l();Oe(o);f.send(e==="get"?null:Xe(v))}function Pe(e){if(a().readyState!=="loading"){e()}else{a().addEventListener("DOMContentLoaded",e)}}h(".kutty-indicator{opacity:0;transition: opacity 200ms ease-in;}");h(".kutty-request .kutty-indicator{opacity:1}");h(".kutty-request.kutty-indicator{opacity:1}");function je(){var e=a().querySelector('meta[name="kutty-config"]');if(e){var t=JSON.parse(e.content);kutty.config=Object.assign(kutty.config,t)}}Pe(function(){je();var e=a().body;de(e);he(e,"load.kutty",{});window.onpopstate=function(){Ce()}});return{onLoad:m,process:de,on:R,off:X,trigger:he,find:C,findAll:L,closest:D,remove:O,addClass:q,removeClass:N,toggleClass:A,takeClass:x,logAll:T,logger:null,config:{historyEnabled:true,historyCacheSize:10,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:100},version:"0.0.1",_:p}}(); \ No newline at end of file diff --git a/dist/kutty.min.js.gz b/dist/kutty.min.js.gz index 62191b65c07a3c3c0374c390ad2819f67146b8e4..e8cf61117c277495a3f827273336c3c72f36ca82 100644 GIT binary patch literal 5682 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\x20\t\r\n\f]*)/i var match = tagMatcher.exec( str ); @@ -163,6 +158,119 @@ var kutty = kutty || (function () { sheet.insertRule(rule, sheet.cssRules.length); } + //========================================================================================== + // public API + //========================================================================================== + + function internalEval(str){ + return eval(str); + } + + function onLoadHelper(callback) { + kutty.on("load.kutty", function(evt) { + callback(evt.detail.elt); + }); + } + + function logAll(){ + kutty.logger = function(elt, event, data) { + if(console) { + console.log(event, elt, data); + } + } + } + + function find(eltOrSelector, selector) { + if (selector) { + eltOrSelector.querySelector(eltOrSelector); + } else { + getDocument().body.querySelector(eltOrSelector); + } + } + + function findAll(eltOrSelector, selector) { + if (selector) { + eltOrSelector.querySelectorAll(eltOrSelector); + } else { + getDocument().body.querySelectorAll(eltOrSelector); + } + } + + function removeElement(elt, delay) { + if (delay) { + setTimeout(function(){removeElement(elt);}, delay) + } else { + elt.parentElement.removeChild(elt); + } + } + + function addClassToElement(elt, clazz, delay) { + if (delay) { + setTimeout(function(){addClassToElement(elt, clazz);}, delay) + } else { + elt.classList.add(clazz); + } + } + + function removeClassFromElement(elt, clazz) { + if (delay) { + setTimeout(function(){removeClassFromElement(elt, clazz);}, delay) + } else { + elt.classList.remove(clazz); + } + } + + function toggleClassOnElement(elt, clazz) { + elt.classList.toggle(clazz); + } + + function takeClassForElement(elt, clazz) { + forEach(elt.parent.children, function(child){ + removeClassFromElement(child, clazz); + }) + addClassToElement(elt, clazz); + } + + function closest(elt, selector) { + do if (elt == null || matches(elt, selector)) return elt; + while (elt = elt && parentElt(elt)); + } + + function processEventArgs(arg1, arg2, arg3) { + if (isFunction(arg2)) { + return { + target: getDocument().body, + event: arg1, + listener: arg2 + } + } else { + return { + target: arg1, + event: arg2, + listener: arg3 + } + } + + } + + function addKuttyEventListener(arg1, arg2, arg3) { + var eventArgs = processEventArgs(arg1, arg2, arg3); + ready(function(){ + eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener); + }) + return eventArgs.listener; + } + + function removeKuttyEventListener(arg1, arg2, arg3) { + var eventArgs = processEventArgs(arg1, arg2, arg3); + ready(function(){ + eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener); + }) + return eventArgs.listener; + } + + + //==================================================================== // Node processing //==================================================================== @@ -208,7 +316,7 @@ var kutty = kutty || (function () { settleTasks = settleTasks.concat(swapOuterHTML(target, fragment)); } else { child.parentNode.removeChild(child); - triggerEvent(getDocument().body, "oobErrorNoTarget.kutty", {content: child}) + triggerErrorEvent(getDocument().body, "oobErrorNoTarget.kutty", {content: child}) } } }); @@ -535,7 +643,7 @@ var kutty = kutty || (function () { triggerEvent(elt, "initSSE.kutty", detail); var source = new EventSource(sseSrc, detail.config); source.onerror = function (e) { - triggerEvent(elt, "sseError.kutty", {error:e, source:source}); + triggerErrorEvent(elt, "sseError.kutty", {error:e, source:source}); maybeCloseSSESource(elt); }; getInternalData(elt).sseSource = source; @@ -557,7 +665,7 @@ var kutty = kutty || (function () { }; sseSource.sseSource.addEventListener(sseEventName, sseListener); } else { - triggerEvent(elt, "noSSESourceError.kutty") + triggerErrorEvent(elt, "noSSESourceError.kutty") } } @@ -651,57 +759,21 @@ var kutty = kutty || (function () { return evt; } + function triggerErrorEvent(elt, eventName, detail) { + triggerEvent(elt, eventName, Object.assign({isError:true}, details)); + } + function triggerEvent(elt, eventName, detail) { detail["elt"] = elt; var event = makeEvent(eventName, detail); if (kutty.logger) { kutty.logger(elt, eventName, detail); - if (eventName.indexOf("Error") > 0) { + if (detail.isError) { sendError(elt, eventName, detail); } } var eventResult = elt.dispatchEvent(event); - var allResult = elt.dispatchEvent(makeEvent("all.kutty", {originalDetail:detail, originalEvent: event})); - return eventResult && allResult; - } - - function processEventArgs(arg1, arg2, arg3) { - if (isFunction(arg1)) { - return { - target: getDocument().body, - event: "all.kutty", - listener: arg1 - } - } else if (isFunction(arg2)) { - return { - target: getDocument().body, - event: arg1, - listener: arg2 - } - } else { - return { - target: arg1, - event: arg2, - listener: arg3 - } - } - - } - - function addKuttyEventListener(arg1, arg2, arg3) { - var eventArgs = processEventArgs(arg1, arg2, arg3); - ready(function(){ - eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener); - }) - return eventArgs.listener; - } - - function removeKuttyEventListener(arg1, arg2, arg3) { - var eventArgs = processEventArgs(arg1, arg2, arg3); - ready(function(){ - eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener); - }) - return eventArgs.listener; + return eventResult; } //==================================================================== @@ -771,7 +843,7 @@ var kutty = kutty || (function () { settleImmediately(swapInnerHTML(getHistoryElement(), fragment)); currentPathForHistory = path; } else { - triggerEvent(getDocument().body, "historyCacheMissLoadError.kutty", details); + triggerErrorEvent(getDocument().body, "historyCacheMissLoadError.kutty", details); } }; request.send(); @@ -1007,7 +1079,7 @@ var kutty = kutty || (function () { function issueAjaxRequest(elt, verb, path, eventTarget) { var target = getTarget(elt); if (target == null) { - triggerEvent(elt, 'targetError.kutty', {target: getRawAttribute(elt, "kt-target")}); + triggerErrorEvent(elt, 'targetError.kutty', {target: getRawAttribute(elt, "kt-target")}); return; } var eltData = getInternalData(elt); @@ -1125,7 +1197,7 @@ var kutty = kutty || (function () { doSettle(); } } catch (e) { - triggerEvent(elt, 'swapError.kutty', eventDetail); + triggerErrorEvent(elt, 'swapError.kutty', eventDetail); throw e; } }; @@ -1137,11 +1209,11 @@ var kutty = kutty || (function () { } } } else { - triggerEvent(elt, 'responseError.kutty', eventDetail); + triggerErrorEvent(elt, 'responseError.kutty', eventDetail); } } catch (e) { eventDetail['exception'] = e; - triggerEvent(elt, 'onLoadError.kutty', eventDetail); + triggerErrorEvent(elt, 'onLoadError.kutty', eventDetail); throw e; } finally { removeRequestIndicatorClasses(elt); @@ -1150,7 +1222,8 @@ var kutty = kutty || (function () { } } xhr.onerror = function () { - removeRequestIndicatorClasses(elt);triggerEvent(elt, 'sendError.kutty', eventDetail); + removeRequestIndicatorClasses(elt); + triggerErrorEvent(elt, 'sendError.kutty', eventDetail); endRequestLock(); } if(!triggerEvent(elt, 'beforeRequest.kutty', eventDetail)) return endRequestLock(); @@ -1194,30 +1267,21 @@ var kutty = kutty || (function () { }; }) - function internalEval(str){ - return eval(str); - } - - function onLoadHelper(callback) { - kutty.on("load.kutty", function(evt) { - callback(evt.detail.elt); - }); - } - - function logAll(){ - kutty.logger = function(elt, event, data) { - if(console) { - console.log(event, elt, data); - } - } - } - // Public API return { + onLoad: onLoadHelper, process: processNode, on: addKuttyEventListener, off: removeKuttyEventListener, - onLoad: onLoadHelper, + trigger : triggerEvent, + find : find, + findAll : findAll, + closest : closest, + remove : removeElement, + addClass : addClassToElement, + removeClass : removeClassFromElement, + toggleClass : toggleClassOnElement, + takeClass : takeClassForElement, logAll : logAll, logger : null, config : { diff --git a/www/_includes/layout.njk b/www/_includes/layout.njk index cbb45600..82812d53 100644 --- a/www/_includes/layout.njk +++ b/www/_includes/layout.njk @@ -45,6 +45,9 @@ +
+ talk +
github diff --git a/www/index.md b/www/index.md index 5fdd01b5..d880f654 100644 --- a/www/index.md +++ b/www/index.md @@ -15,7 +15,7 @@ Kutty is a set of extensions (attributes, request headers, etc.) that help you b [advanced UX](/examples) with the [simplicity](https://en.wikipedia.org/wiki/HATEOAS) and [power](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) of HTML. -Kutty is small ([~5Kb min.gz'd](https://unpkg.com/kutty.org/dist/)), [dependency-free](https://github.com/bigskysoftware/kutty/blob/master/package.json) +Kutty is small ([~6k min.gz'd](https://unpkg.com/kutty.org/dist/)), [dependency-free](https://github.com/bigskysoftware/kutty/blob/master/package.json) & you can try it out quickly, without a huge rewrite. ## Quick Start diff --git a/www/posts/2020-5-15-kutty-0.0.1-is-released.md b/www/posts/2020-5-15-kutty-0.0.1-is-released.md new file mode 100644 index 00000000..51c7be6d --- /dev/null +++ b/www/posts/2020-5-15-kutty-0.0.1-is-released.md @@ -0,0 +1,40 @@ +--- +layout: layout.njk +title: kutty - high power tools for html +--- + +## Kutty 0.0.1 Release + +I'm pleased to announce the [first release](https://unpkg.com/browse/kutty.org@0.0.1/) of kutty, the successor +to [intercooler.js](http://intercoolerjs.org)! + +Like intercooler, kutty brings the power of modern browsers into HTML. + + +#### What's new/different about kutty vs. intercooler? + +* First and foremost, kutty has no external dependencies! No more dragging jQuery in if you don't want it. +* I've tried to follow conventional naming and behavior standards more closely where applicable (e.g. [`innerHTML`](/attributes/kt-swap) and [`outerHTML`](/attributes/kt-swap)) +* Kutty is less kitchen-sink-of-features and more pluggable than intercooler +* Kutty has a better swapping mechanism which introduces a settling step, which allows for nice CSS transitions + without plain old HTML + +Beyond that, basic kutty and intercooler code will look a lot a like: + +```html +
Click Me!
+``` + +This will issue an AJAX post to `/clicked`, in a manner familiar to anyone who has used intercooler. + +#### What will happen to intercooler? + +I'm planning on maintaining both projects. Intercooler is a slow moving project anyway, and the code is stable and +works fine for people who want to go the jQuery route. I have a large application written with it and I'm not planning +on moving that to kutty any time soon. + +#### How hard will a port to kutty from intercooler be? + +Depends a lot on how into the weeds you got with intercooler. The core attributes are pretty close to one another +but if you were using `ic-action` or event handlers extensively it will be a project. That's why I chose to rename it, +and to continue to maintain intercooler. \ No newline at end of file diff --git a/www/talk.md b/www/talk.md new file mode 100644 index 00000000..3ae2e27e --- /dev/null +++ b/www/talk.md @@ -0,0 +1,17 @@ +--- +layout: layout.njk +title: kutty - high power tools for html +--- + +## Talk Kutty + +Right now the best place to talk about kutty is the [intercooler gitter room](https://gitter.im/intercooler-js/Lobby) + +I'll be setting up a forum and + +## Announcements + +I'm trying to set up a blog [here](/posts) + + +