From dba9904af86d7b168b3dd2e5d2f1b594dc7b49fe Mon Sep 17 00:00:00 2001 From: carson Date: Sat, 9 May 2020 12:41:12 -0700 Subject: [PATCH] remove attributes in favor of a single `kt-classes` attribute w/ some syntax --- src/kutty.js | 74 ++++++++++++++++++++++++++---------- test/classes.js | 6 +-- www/attributes.md | 5 +-- www/attributes/kt-classes.md | 34 +++++++++++++++++ 4 files changed, 92 insertions(+), 27 deletions(-) create mode 100644 www/attributes/kt-classes.md diff --git a/src/kutty.js b/src/kutty.js index 1e18a7d0..64392416 100644 --- a/src/kutty.js +++ b/src/kutty.js @@ -118,6 +118,10 @@ var kutty = kutty || (function () { return arr1.concat(arr2); } + function splitOnWhitespace(trigger) { + return trigger.split(/\s+/); + } + //==================================================================== // Node processing //==================================================================== @@ -303,22 +307,54 @@ var kutty = kutty || (function () { } } - function processClassList(elt, classList, operation) { - var values = classList.split(","); - forEach(values, function(value){ - var cssClass = ""; - var delay = 50; - var trimmedValue = value.trim(); - if (trimmedValue.indexOf(":") > 0) { - var split = trimmedValue.split(':'); - cssClass = split[0]; - delay = parseInterval(split[1]); + function parseClassOperation(trimmedValue) { + var split = splitOnWhitespace(trimmedValue); + if (split.length > 1) { + var operation = split[0]; + var classDef = split[1].trim(); + var cssClass; + var delay; + if (classDef.indexOf(":") > 0) { + var splitCssClass = classDef.split(':'); + cssClass = splitCssClass[0]; + delay = parseInterval(splitCssClass[1]); } else { - cssClass = trimmedValue; + cssClass = classDef; + delay = 100; } - setTimeout(function () { - elt.classList[operation].call(elt.classList, cssClass); - }, delay); + return { + operation:operation, + cssClass:cssClass, + delay:delay + } + } else { + return null; + } + } + + function processClassList(elt, classList, operation) { + forEach(classList.split("&"), function (run) { + var currentRunTime = 0; + forEach(run.split(","), function(value){ + var cssClass = ""; + var trimmedValue = value.trim(); + var classOperation = parseClassOperation(trimmedValue); + if (classOperation) { + if (classOperation.operation === "toggle") { + setTimeout(function () { + setInterval(function () { + elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass); + }, classOperation.delay); + }, currentRunTime); + currentRunTime = currentRunTime + classOperation.delay; + } else { + currentRunTime = currentRunTime + classOperation.delay; + setTimeout(function () { + elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass); + }, currentRunTime); + } + } + }); }); } @@ -326,7 +362,7 @@ var kutty = kutty || (function () { var trigger = getTrigger(elt); var nodeData = getInternalData(elt); if (trigger.trim().indexOf("every ") === 0) { - var args = trigger.split(/\s+/); + var args = splitOnWhitespace(trigger); var intervalStr = args[1]; if (intervalStr) { var interval = parseInterval(intervalStr); @@ -517,13 +553,9 @@ var kutty = kutty || (function () { if (sseSrc) { initSSESource(elt, sseSrc); } - var addClass = getAttributeValue(elt, 'kt-add-class'); + var addClass = getAttributeValue(elt, 'kt-classes'); if (addClass) { - processClassList(elt, addClass, "add"); - } - var removeClass = getAttributeValue(elt, 'kt-remove-class'); - if (removeClass) { - processClassList(elt, removeClass, "remove"); + processClassList(elt, addClass); } } if (elt.children) { // IE diff --git a/test/classes.js b/test/classes.js index bd1b9594..17cafb9d 100644 --- a/test/classes.js +++ b/test/classes.js @@ -1,4 +1,4 @@ -describe("kutty class modification attributes", function(){ +describe("kutty classes modification attribute", function(){ beforeEach(function() { this.server = makeServer(); clearWorkArea(); @@ -10,7 +10,7 @@ describe("kutty class modification attributes", function(){ it('adds classes properly', function(done) { - var div = make('
Click Me!
') + var div = make('
Click Me!
') should.equal(div.classList.length, 0); setTimeout(function(){ should.equal(div.classList.contains("c1"), true); @@ -20,7 +20,7 @@ describe("kutty class modification attributes", function(){ it('removes classes properly', function(done) { - var div = make('
Click Me!
') + var div = make('
Click Me!
') should.equal(div.classList.contains("foo"), true); should.equal(div.classList.contains("bar"), true); setTimeout(function(){ diff --git a/www/attributes.md b/www/attributes.md index ac602f53..abba8b83 100644 --- a/www/attributes.md +++ b/www/attributes.md @@ -7,8 +7,8 @@ title: kutty - Attributes | Attribute | Description | |-----------|-------------| -| kt-add-class | TODO - Description | kt-boost | TODO - Description +| [kt-classes](/attributes/kt-classes) | timed modification of classes on an element | kt-confirm | TODO - Description | kt-delete | TODO - Description | kt-error-url | TODO - Description @@ -22,11 +22,10 @@ title: kutty - Attributes | kt-prompt | TODO - Description | kt-push-url | TODO - Description | kt-put | TODO - Description -| kt-remove-class | TODO - Description | kt-select | TODO - Description | kt-settle-delay | TODO - Description | kt-sse-src | TODO - Description -| kt-swap | TODO - Description +| [kt-swap](/attributes/kt-swap) | TODO - Description | kt-swap-delay | TODO - Description | kt-swap-oob | TODO - Description | kt-target | TODO - Description diff --git a/www/attributes/kt-classes.md b/www/attributes/kt-classes.md new file mode 100644 index 00000000..724c38b8 --- /dev/null +++ b/www/attributes/kt-classes.md @@ -0,0 +1,34 @@ +--- +layout: layout.njk +title: kutty - kt-classes +--- + +## `kt-classes` + +The `kt-classes` attribute allows you to specify CSS classes that will be swapped onto the element that +the attribute is on. This allows you to apply [CSS Transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions) +to your HTML without resorting to javascript. + +A `kt-classes` attribute value consists of "runs", which are separated by an `&` character. All +class operations within a given run will be applied sequentially, with the delay specified. + +Within a run, a `,` character separates distinct class operations. + +A class operation is an operation name `add`, `remove`, or `toggle`, followed by a CSS class name, +optionally followed by a colon `:` and a time delay. + +Here are some examples: + +```html +
+
+
+
+
+``` + +### Notes + +* The default delay if none is specified is 100ms