Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions src/_hyperscript.js
Original file line number Diff line number Diff line change
Expand Up @@ -6521,10 +6521,20 @@
var onExpr = parser.requireElement("implicitMeTarget", tokens);
}
} 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) {
var betweenClass = true;
tokens.requireToken("and");
var classRef2 = parser.requireElement("classRef", tokens);
} else {
var betweenAttr = true
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;
Expand Down Expand Up @@ -6563,6 +6573,7 @@
classRef2: classRef2,
classRefs: classRefs,
attributeRef: attributeRef,
attributeRef2: attributeRef2,
on: onExpr,
time: time,
evt: evt,
Expand All @@ -6573,7 +6584,7 @@
runtime.implicitLoop(on, function (target) {
hideShowStrategy("toggle", target);
});
} else if (between) {
} else if (betweenClass) {
runtime.implicitLoop(on, function (target) {
if (target.classList.contains(classRef.className)) {
target.classList.remove(classRef.className);
Expand All @@ -6583,6 +6594,17 @@
target.classList.remove(classRef2.className);
}
});
} else if (betweenAttr) {
runtime.implicitLoop(on, function (target) {
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) {
runtime.forEach(classRefs, function (classRef) {
runtime.implicitLoop(on, function (target) {
Expand Down
21 changes: 21 additions & 0 deletions test/commands/toggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 data-state='active' _='on click toggle between [@data-state=\"active\"] and [@data-state=\"inactive\"]'></div>");
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 enabled='true' _='on click toggle between [@enabled=\"true\"] and [@disabled=\"true\"]'></div>");
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);
});
});
12 changes: 10 additions & 2 deletions www/commands/toggle.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: toggle - ///_hyperscript
### Syntax

```ebnf
toggle ({<class-ref>} | <attribute-ref> | between <class-ref> and <class-ref>)
toggle ({<class-ref>} | <attribute-ref> | between (<class-ref> | <attribute-ref>) and (<class-ref> | <attribute-ref>))
[on <expression>]
[(for <time expression>) |
(until <event name> [from <expression>]]`
Expand All @@ -31,7 +31,7 @@ The `toggle` command allows you to toggle:
on either the current element or, if a [target expression](/expressions)
is provided, to the targeted element(s).

You can use the form `toggle between .class1 and .class2` to flip between two classes.
You can use the form `toggle between .class1 and .class2` to flip between two classes, or `toggle between [@attr1='value1'] and [@attr2='value2']` to flip between attributes.

If you provide a `for <time expression>` the class or attribute will be toggled for that amount of time.

Expand All @@ -57,6 +57,14 @@ If you provide an `until <event name>` the class or attribute will be toggled un
Toggle Me!
</button>

<button _="on click toggle between [@data-state='active'] and [@data-state='inactive']">
Toggle State!
</button>

<button _="on click toggle between [@enabled='true'] and [@disabled='true']">
Toggle Attributes!
</button>

<button _="on click toggle *display on the next <div/>">
Toggle Me!
</button>
Expand Down