Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Support negation operator in selectors #232

Merged
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
29 changes: 29 additions & 0 deletions e2e/html/negation-operator.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<title>Negation Operator</title>
<meta itemprop="wp-client-side-navigation" content="active" />
</head>
<body>
<button
data-wp-on.click="actions.toggle"
data-testid="toggle active value"
>
Toggle Active Value
</button>

<div
data-wp-bind.hidden="!state.active"
data-testid="add hidden attribute if state is not active"
></div>

<div
data-wp-bind.hidden="!selectors.active"
data-testid="add hidden attribute if selector is not active"
></div>

<script defer src="../../build/e2e/negation-operator.js"></script>
<script defer src="../../build/runtime.js"></script>
<script defer src="../../build/vendors.js"></script>
</body>
</html>
17 changes: 17 additions & 0 deletions e2e/js/negation-operator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { store } from '../../src/runtime/store';

store({
selectors: {
active: ({ state }) => {
return state.active;
},
},
state: {
active: false,
},
actions: {
toggle: ({ state }) => {
state.active = !state.active;
},
},
});
31 changes: 31 additions & 0 deletions e2e/specs/negation-operator.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { test, expect } from '../tests';

test.describe('negation-operator', () => {
test.beforeEach(async ({ goToFile }) => {
await goToFile('negation-operator.html');
});

test('add hidden attribute when !state.active', async ({ page }) => {
const el = page.getByTestId(
'add hidden attribute if state is not active'
);

await expect(el).toHaveAttribute('hidden', '');
page.getByTestId('toggle active value').click();
await expect(el).not.toHaveAttribute('hidden', '');
page.getByTestId('toggle active value').click();
await expect(el).toHaveAttribute('hidden', '');
});

test('add hidden attribute when !selectors.active', async ({ page }) => {
const el = page.getByTestId(
'add hidden attribute if selector is not active'
);

await expect(el).toHaveAttribute('hidden', '');
page.getByTestId('toggle active value').click();
await expect(el).not.toHaveAttribute('hidden', '');
page.getByTestId('toggle active value').click();
await expect(el).toHaveAttribute('hidden', '');
});
});
22 changes: 12 additions & 10 deletions src/runtime/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,27 @@ export const directive = (name, cb) => {

// Resolve the path to some property of the store object.
const resolve = (path, ctx) => {
// If path starts with !, remove it and save a flag.
const hasNegationOperator = path[0] === '!' && !!(path = path.slice(1));
let current = { ...store, context: ctx };
path.split('.').forEach((p) => (current = current[p]));
return hasNegationOperator ? !current : current;
return current;
};

// Generate the evaluate function.
const getEvaluate =
({ ref } = {}) =>
(path, extraArgs = {}) => {
// If path starts with !, remove it and save a flag.
const hasNegationOperator = path[0] === '!' && !!(path = path.slice(1));
const value = resolve(path, extraArgs.context);
return typeof value === 'function'
? value({
ref: ref.current,
...store,
...extraArgs,
})
: value;
const returnValue =
typeof value === 'function'
? value({
ref: ref.current,
...store,
...extraArgs,
})
: value;
return hasNegationOperator ? !returnValue : returnValue;
};

// Directive wrapper.
Expand Down
1 change: 1 addition & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = [
'e2e/page-2': './e2e/page-2',
'e2e/directive-bind': './e2e/js/directive-bind',
'e2e/directive-effect': './e2e/js/directive-effect',
'e2e/negation-operator': './e2e/js/negation-operator',
},
output: {
filename: '[name].js',
Expand Down