Skip to content

Commit

Permalink
fix(SignalControllers): Fix bug preventing OR expressions ever return…
Browse files Browse the repository at this point in the history
…ing true
  • Loading branch information
Sub-Xaero committed Dec 13, 2023
1 parent 558c77e commit 10bffb2
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 25 deletions.
24 changes: 16 additions & 8 deletions packages/controllers/src/signal/base_controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BaseController, EventBus } from "@stimulus-library/utilities";
import { SignalPayload } from "./signal_input_controller";
import { extractPredicates } from "./expressions";
import { extractExpressions, extractPredicates } from "./expressions";
import { signalConnectEvent, signalValueEvent } from "./events";
import { useEventBus } from "@stimulus-library/mixins";

Expand All @@ -12,11 +12,6 @@ export abstract class SignalBaseController extends BaseController {

declare nameValue: string;

connect() {
EventBus.emit(signalConnectEvent(this.nameValue));
useEventBus(this, signalValueEvent(this.nameValue), this._onSignal);
}

get predicateString() {
return "";
}
Expand All @@ -25,8 +20,21 @@ export abstract class SignalBaseController extends BaseController {
return extractPredicates(this.predicateString);
}

allPredicatesMatch(value: SignalPayload["value"]): boolean {
return this._predicates.every(predicate => predicate(value));
get _expressions(): Array<string> {
return extractExpressions(this.predicateString);
}

connect() {
EventBus.emit(signalConnectEvent(this.nameValue));
useEventBus(this, signalValueEvent(this.nameValue), this._onSignal);
}

predicatesMatch(value: SignalPayload["value"]): boolean {
if (this.predicateString.includes("||")) {
return this._predicates.some(predicate => predicate(value));
} else {
return this._predicates.every(predicate => predicate(value));
}
}

abstract _onSignal(payload: SignalPayload): void;
Expand Down
8 changes: 7 additions & 1 deletion packages/controllers/src/signal/expressions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export function extractExpressions(expressionString: string): Array<string> {
const andExpression = expressionString.includes("&&");
return expressionString.split(andExpression ? "&&" : "||");
}

export function extractPredicates(expressionString: string): Array<(val: string | number) => boolean> {
expressionString = expressionString.trim();

Expand All @@ -13,7 +18,8 @@ export function extractPredicates(expressionString: string): Array<(val: string
throw new Error("Cannot have logical groupings `(>3 && <= 9) || (>1 && <2)` in the expression. Only supports simple expressions like `>1 && <3`");
}

const expressions = expressionString.split(andExpression ? "&&" : "||");
const expressions = extractExpressions(expressionString);

if (andExpression) {
return expressions.map(ex => _predicateForExpression(ex));
} else if (orExpression) {
Expand Down
24 changes: 21 additions & 3 deletions packages/controllers/src/signal/signal_action_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,28 @@ export class SignalActionController extends SignalBaseController {
this.dispatchEvent(this.el, signalEventName(this.nameValue, "match"));
return;
}
if (this.allPredicatesMatch(value)) {
this.dispatchEvent(this.el, signalEventName(this.nameValue, "match"), {detail: {element: this.el, value}});
if (this.predicatesMatch(value)) {
this.dispatchEvent(
this.el,
signalEventName(this.nameValue, "match"),
{
detail: {
element: this.el,
value,
},
},
);
} else {
this.dispatchEvent(this.el, signalEventName(this.nameValue, "no-match"), {detail: {element: this.el, value}});
this.dispatchEvent(
this.el,
signalEventName(this.nameValue, "no-match"),
{
detail: {
element: this.el,
value,
},
},
);
}
}

Expand Down
28 changes: 19 additions & 9 deletions packages/controllers/src/signal/signal_disable_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,29 @@ export class SignalDisableController extends SignalBaseController {
}
return;
}
if (this.allPredicatesMatch(value)) {
this.dispatchEvent(this.el, signalEventName(this.nameValue, "disable"), {
detail: {
predicate: this.whenValue, value,
if (this.predicatesMatch(value)) {
this.dispatchEvent(
this.el,
signalEventName(this.nameValue, "disable"),
{
detail: {
predicate: this.whenValue,
value,
},
},
});
);
this.disable();
} else {
this.dispatchEvent(this.el, signalEventName(this.nameValue, "enable"), {
detail: {
predicate: this.whenValue, value,
this.dispatchEvent(
this.el,
signalEventName(this.nameValue, "enable"),
{
detail: {
predicate: this.whenValue,
value,
},
},
});
);
this.enable();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class SignalEnableController extends SignalBaseController {
}
return;
}
if (this.allPredicatesMatch(value)) {
if (this.predicatesMatch(value)) {
this.dispatchEvent(this.el, signalEventName(this.nameValue, "enable"), {
detail: {
predicate: this.whenValue,
Expand Down
24 changes: 21 additions & 3 deletions packages/controllers/src/signal/signal_visibility_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,29 @@ export class SignalVisibilityController extends SignalBaseController {
}
return;
}
if (this.allPredicatesMatch(value)) {
this.dispatchEvent(this.el, signalVisibilityEvent(this.nameValue, "show"), {detail: {predicate: this.showValue, value}});
if (this.predicatesMatch(value)) {
this.dispatchEvent(
this.el,
signalVisibilityEvent(this.nameValue, "show"),
{
detail: {
predicate: this.showValue,
value
}
}
);
this.removeHideClasses(this.el);
} else {
this.dispatchEvent(this.el, signalVisibilityEvent(this.nameValue, "hide"), {detail: {predicate: this.showValue, value}});
this.dispatchEvent(
this.el,
signalVisibilityEvent(this.nameValue, "hide"),
{
detail: {
predicate: this.showValue,
value
}
}
);
this.addHideClasses(this.el);
}
}
Expand Down

0 comments on commit 10bffb2

Please sign in to comment.