Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix events handling #1330

Merged
merged 12 commits into from
Jul 16, 2024
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ Changelog

_Note: Gaps between patch versions are faulty, broken or test releases._

## v4.0.0-beta.?? (2024-??-??)
## v4.0.0-beta.?? (2024-07-??)

#### :bug: Bug Fix

* `core/page-meta-data` is now expects description element to be a `meta` tag with the attribute `name='description'` instead of the `description` tag
* Fixed the bug where the event name was set as an event modifier in the `v-attrs` directive `component/directives/attrs`
* Replaced the method calls to `componentCtx.$once` and `componentCtx.$on` with correct event handling based on the isOnceEvent flag in `component/directives/attrs`
* The page description element is now expected to be a meta tag
with the attribute `name='description'` instead of the `description` tag `core/page-meta-data`

## v4.0.0-beta.109 (2024-07-16)

Expand Down
34 changes: 33 additions & 1 deletion components-lock.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"hash": "15411bb6fc6333136ec99f5c984bb570c85b97c71e2b98013e9944322c2c9a81",
"hash": "8d68ddaef9f57e4029a54ee2d137723f31596aa0e8a298cb8a9be6102e8374cf",
"data": {
"%data": "%data:Map",
"%data:Map": [
Expand Down Expand Up @@ -149,6 +149,38 @@
"etpl": null
}
],
[
"b-component-emitter-dummy",
{
"index": "src/core/component/directives/attrs/test/b-component-emitter-dummy/index.js",
"declaration": {
"name": "b-component-emitter-dummy",
"parent": "i-block",
"dependencies": [],
"libs": []
},
"name": "b-component-emitter-dummy",
"parent": "i-block",
"dependencies": [],
"libs": [],
"resolvedLibs": {
"%data": "%data:Set",
"%data:Set": []
},
"resolvedOwnLibs": {
"%data": "%data:Set",
"%data:Set": []
},
"type": "block",
"mixin": false,
"logic": "src/core/component/directives/attrs/test/b-component-emitter-dummy/b-component-emitter-dummy.ts",
"styles": [
"src/core/component/directives/attrs/test/b-component-emitter-dummy/b-component-emitter-dummy.styl"
],
"tpl": "src/core/component/directives/attrs/test/b-component-emitter-dummy/b-component-emitter-dummy.ss",
"etpl": null
}
],
[
"b-component-interface-dummy",
{
Expand Down
7 changes: 7 additions & 0 deletions src/core/component/directives/attrs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ Changelog
> - :house: [Internal]
> - :nail_care: [Polish]

## v4.0.0-beta.?? (2024-07-??)

#### :bug: Bug Fix

* Fixed the bug where the event name was set as an event modifier in the `v-attrs` directive
* Replaced the method calls to `componentCtx.$once` and `componentCtx.$on` with correct event handling based on the isOnceEvent flag

## v4.0.0-alpha.1 (2022-12-14)

#### :rocket: New Feature
Expand Down
26 changes: 15 additions & 11 deletions src/core/component/directives/attrs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ import {
import type { ComponentInterface } from 'core/component/interface';
import type { DirectiveParams } from 'core/component/directives/attrs/interface';

//#if runtime has dummyComponents
import('core/component/directives/attrs/test/b-component-directives-emitter-dummy');
//#endif

export * from 'core/component/directives/attrs/const';
export * from 'core/component/directives/attrs/interface';

Expand Down Expand Up @@ -224,8 +228,7 @@ ComponentEngine.directive('attrs', {
modifiers
};

const
cantIgnoreDir = value != null || decl.length !== 2;
const cantIgnoreDir = value != null || decl.length !== 2;

if (Object.isDictionary(dir)) {
if (Object.isFunction(dir.beforeCreate)) {
Expand Down Expand Up @@ -258,18 +261,18 @@ ComponentEngine.directive('attrs', {
function parseEventListener(attrName: string, attrVal: unknown) {
let
isDOMEvent = true,
event = attrName.slice(1).camelize(false);
event = attrName.slice(1).camelize(false),
isOnceEvent = false;

const
originalEvent = event,
eventChunks = event.split('.');

const
flags = Object.createDict<boolean>(),
isOnceEvent = flags.once;
eventChunks = event.split('.'),
flags = Object.createDict<boolean>();

eventChunks.forEach((chunk) => flags[chunk] = true);
// The first element is the event name; we need to slice only the part containing the event modifiers
eventChunks.slice(1).forEach((chunk) => flags[chunk] = true);
shining-mind marked this conversation as resolved.
Show resolved Hide resolved
event = eventChunks[0];
isOnceEvent = Boolean(flags.once);

if (flags.right && !event.startsWith('key')) {
event = 'onContextmenu';
Expand Down Expand Up @@ -314,12 +317,13 @@ ComponentEngine.directive('attrs', {
}
}

// FIXME: `componentCtx` is always undefined https://github.com/V4Fire/Client/issues/1336
if (componentCtx != null && !isDOMEvent && Object.isFunction(attrVal)) {
if (isOnceEvent) {
componentCtx.$on(originalEvent, attrVal);
componentCtx.$once(originalEvent, attrVal);
shining-mind marked this conversation as resolved.
Show resolved Hide resolved

} else {
componentCtx.$once(originalEvent, attrVal);
componentCtx.$on(originalEvent, attrVal);
}

} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- namespace [%fileName%]

/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

- include 'components/super/i-block'|b as placeholder

- template index() extends ['i-block'].index
- block body
< button @click = () => onClick() | -testid = deleteButton
delete
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

@import "components/super/i-block/i-block.styl"

$p = {

}

b-component-directives-emitter-dummy extends i-block
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

/* eslint-disable @v4fire/require-jsdoc */

import iBlock, { component, system } from 'components/super/i-block/i-block';

export * from 'components/super/i-block/i-block';

@component({functional: true})
export default class bComponentDirectivesEmitterDummy extends iBlock {
@system()
counter: number = 0;

onClick(): void {
this.emit('delete');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

package('b-component-directives-emitter-dummy')
.extends('i-block');
85 changes: 85 additions & 0 deletions src/core/component/directives/attrs/test/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/

import type { ElementHandle, JSHandle, Locator, Page } from 'playwright';

import { Component } from 'tests/helpers';

import type { Watcher } from 'components/directives/on-resize';

import type bComponentDirectivesEmitterDummy from 'core/component/directives/attrs/test/b-component-directives-emitter-dummy/b-component-directives-emitter-dummy';

export function renderDummy(
page: Page,
attrs: RenderComponentsVnodeParams['attrs']
): Promise<JSHandle<bComponentDirectivesEmitterDummy>> {
return Component.createComponent<bComponentDirectivesEmitterDummy>(page, 'b-component-directives-emitter-dummy', {
'data-testid': 'target',
'v-attrs': {
...attrs
}
});
}

export async function renderDirective(
page: Page,
componentName: string,
attrs: RenderComponentsVnodeParams['attrs']
): Promise<Locator> {
const componentTestId = 'target';

await Component.createComponent(page, componentName, {
'data-testid': componentTestId,
'data-counter': 0,
'v-attrs': {...attrs},
style: 'width: 100px; height: 100px'
});

return page.getByTestId(componentTestId);
}

export async function waitForWatcherCallsCount(page: Page, observedEl: Locator, expected: number): Promise<void> {
const handle = await observedEl.elementHandle();

await page
.waitForFunction(
([div, val]) => Boolean(
div.getAttribute('data-counter') === val.toString(10)
),

<[ElementHandle<HTMLElement>, number]>[handle, expected]
);
}

export function resizeHandler(newRect: DOMRect, oldRect: DOMRect, watcher: Watcher): void {
const {target} = watcher;

const previousValue = parseInt(
target.getAttribute('data-counter') ?? '0',
10
);

const nextValue = previousValue + 1;
target.setAttribute('data-counter', nextValue.toString());
}

export function clickHandler(event: MouseEvent): void {
const target = <Element>event.target;

const previousValue = parseInt(
target.getAttribute('data-counter') ?? '0',
10
);

const nextValue = previousValue + 1;
target.setAttribute('data-counter', nextValue.toString());
}

export function dummyDeleteHandler(target: bComponentDirectivesEmitterDummy): void {
target.counter++;
}
Loading
Loading