From 7ef6c26234a3276f4e6d2335b00aeba60cbac039 Mon Sep 17 00:00:00 2001 From: MichaelWest22 Date: Wed, 6 Aug 2025 20:37:26 +1200 Subject: [PATCH 1/2] toggle between attributes --- src/_hyperscript.js | 37 +++++++++++++++++++++++++++++-------- test/commands/toggle.js | 21 +++++++++++++++++++++ www/commands/toggle.md | 12 ++++++++++-- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/_hyperscript.js b/src/_hyperscript.js index 01be8755d..fd832963c 100644 --- a/src/_hyperscript.js +++ b/src/_hyperscript.js @@ -6523,8 +6523,17 @@ } else if (tokens.matchToken("between")) { var between = true; var classRef = parser.parseElement("classRef", tokens); - tokens.requireToken("and"); - var classRef2 = parser.requireElement("classRef", tokens); + if (classRef != null) { + tokens.requireToken("and"); + var classRef2 = parser.requireElement("classRef", tokens); + } else { + var attributeRef = parser.parseElement("attributeRef", tokens); + if (attributeRef == null) { + parser.raiseParseError(tokens, "Expected either a class reference or attribute expression"); + } + tokens.requireToken("and"); + var attributeRef2 = parser.requireElement("attributeRef", tokens); + } } else { var classRef = parser.parseElement("classRef", tokens); var attributeRef = null; @@ -6563,6 +6572,7 @@ classRef2: classRef2, classRefs: classRefs, attributeRef: attributeRef, + attributeRef2: attributeRef2, on: onExpr, time: time, evt: evt, @@ -6575,12 +6585,23 @@ }); } else if (between) { runtime.implicitLoop(on, function (target) { - if (target.classList.contains(classRef.className)) { - target.classList.remove(classRef.className); - target.classList.add(classRef2.className); - } else { - target.classList.add(classRef.className); - target.classList.remove(classRef2.className); + if (classRef && classRef2) { + if (target.classList.contains(classRef.className)) { + target.classList.remove(classRef.className); + target.classList.add(classRef2.className); + } else { + target.classList.add(classRef.className); + target.classList.remove(classRef2.className); + } + } else if (attributeRef && attributeRef2) { + var currentValue = target.getAttribute(attributeRef.name); + if (currentValue === attributeRef.value) { + target.setAttribute(attributeRef2.name, attributeRef2.value); + if (attributeRef.name !== attributeRef2.name) target.removeAttribute(attributeRef.name); + } else { + target.setAttribute(attributeRef.name, attributeRef.value); + if (attributeRef.name !== attributeRef2.name) target.removeAttribute(attributeRef2.name); + } } }); } else if (classRefs) { diff --git a/test/commands/toggle.js b/test/commands/toggle.js index 5a46c5627..f39b08595 100644 --- a/test/commands/toggle.js +++ b/test/commands/toggle.js @@ -196,4 +196,25 @@ describe("the toggle command", function () { form.click(); form.classList.contains("group-[:nth-of-type(3)_&]:block").should.equal(false); }); + + it("can toggle between two attribute values", function () { + var div = make("
"); + div.getAttribute("data-state").should.equal("active"); + div.click(); + div.getAttribute("data-state").should.equal("inactive"); + div.click(); + div.getAttribute("data-state").should.equal("active"); + }); + + it("can toggle between different attributes", function () { + var div = make("
"); + div.getAttribute("enabled").should.equal("true"); + div.hasAttribute("disabled").should.equal(false); + div.click(); + div.hasAttribute("enabled").should.equal(false); + div.getAttribute("disabled").should.equal("true"); + div.click(); + div.getAttribute("enabled").should.equal("true"); + div.hasAttribute("disabled").should.equal(false); + }); }); diff --git a/www/commands/toggle.md b/www/commands/toggle.md index 554bb7d32..c6678d86f 100644 --- a/www/commands/toggle.md +++ b/www/commands/toggle.md @@ -7,7 +7,7 @@ title: toggle - ///_hyperscript ### Syntax ```ebnf -toggle ({} | | between and ) +toggle ({} | | between ( | ) and ( | )) [on ] [(for