Skip to content

Commit 27b3a1e

Browse files
committed
Working WIP implementation
1 parent 062e663 commit 27b3a1e

File tree

3 files changed

+94
-11
lines changed

3 files changed

+94
-11
lines changed

src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static RenderTreeDiff ComputeDiff(
3838
}
3939

4040
public static void DisposeFrames(RenderBatchBuilder batchBuilder, int componentId, ArrayRange<RenderTreeFrame> frames)
41-
=> DisposeFramesInRange(batchBuilder, componentId, frames.Array, 0, frames.Count);
41+
=> DisposeFramesInRange(batchBuilder, componentId, frames.Array, 0, frames.Count, 0);
4242

4343
private static void AppendDiffEntriesForRange(
4444
ref DiffContext diffContext,
@@ -867,7 +867,7 @@ private static void RemoveOldFrame(ref DiffContext diffContext, int oldFrameInde
867867
case RenderTreeFrameType.Element:
868868
{
869869
var endIndexExcl = oldFrameIndex + oldFrame.ElementSubtreeLengthField;
870-
DisposeFramesInRange(diffContext.BatchBuilder, diffContext.ComponentId, oldTree, oldFrameIndex, endIndexExcl);
870+
DisposeFramesInRange(diffContext.BatchBuilder, diffContext.ComponentId, oldTree, oldFrameIndex, endIndexExcl, diffContext.SiblingIndex);
871871
diffContext.Edits.Append(RenderTreeEdit.RemoveFrame(diffContext.SiblingIndex));
872872
break;
873873
}
@@ -1013,7 +1013,7 @@ private static void InitializeNewNamedEvent(ref DiffContext diffContext, int new
10131013
diffContext.BatchBuilder.AddNamedEvent(diffContext.ComponentId, newTreeFrameIndex, ref diffContext.NewTree[newTreeFrameIndex]);
10141014
}
10151015

1016-
private static void DisposeFramesInRange(RenderBatchBuilder batchBuilder, int componentId, RenderTreeFrame[] frames, int startIndex, int endIndexExcl)
1016+
private static void DisposeFramesInRange(RenderBatchBuilder batchBuilder, int componentId, RenderTreeFrame[] frames, int startIndex, int endIndexExcl, int siblingIndex)
10171017
{
10181018
for (var i = startIndex; i < endIndexExcl; i++)
10191019
{
@@ -1022,9 +1022,16 @@ private static void DisposeFramesInRange(RenderBatchBuilder batchBuilder, int co
10221022
{
10231023
batchBuilder.ComponentDisposalQueue.Enqueue(frame.ComponentIdField);
10241024
}
1025-
else if (frame.FrameTypeField == RenderTreeFrameType.Attribute && frame.AttributeEventHandlerIdField > 0)
1025+
else if (frame.FrameTypeField == RenderTreeFrameType.Attribute)
10261026
{
1027-
batchBuilder.DisposedEventHandlerIds.Append(frame.AttributeEventHandlerIdField);
1027+
if (frame.AttributeEventHandlerIdField > 0)
1028+
{
1029+
batchBuilder.DisposedEventHandlerIds.Append(frame.AttributeEventHandlerIdField);
1030+
}
1031+
else if (frame.AttributeValueField is bool boolValue && boolValue && frame.AttributeNameField.StartsWith("__internal_", StringComparison.Ordinal))
1032+
{
1033+
batchBuilder.EditsBuffer.Append(RenderTreeEdit.RemoveAttribute(siblingIndex, frame.AttributeNameField));
1034+
}
10281035
}
10291036
else if (frame.FrameTypeField == RenderTreeFrameType.NamedEvent)
10301037
{
Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,60 @@
11
@page "/counter"
22
@rendermode InteractiveServer
3+
@inject IJSRuntime jsRuntime
4+
5+
<style>
6+
body {
7+
height: 3000px;
8+
}
9+
</style>
10+
311
<PageTitle>Counter</PageTitle>
412

513
<h1>Counter</h1>
614

715
<p role="status">Current count: @currentCount</p>
16+
<p>showElements: @showElements</p>
17+
<p>preventDefault: @preventDefault</p>
18+
19+
@if (showElements)
20+
{
21+
<div @onwheel:preventDefault="preventDefault" style="width: 600px; height: 200px; border: 1px solid black;">
22+
Try scrolling here
23+
</div>
24+
25+
<button class="btn btn-primary" @onclick="IncrementCount" @onmousedown:preventDefault="preventDefault">
26+
Click me
27+
</button>
28+
}
829

9-
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
30+
<p>
31+
<button class="btn btn-secondary" @onclick="ToggleShow">
32+
Toggle show
33+
</button>
34+
<button class="btn btn-secondary" @onclick="TogglePreventDefault">
35+
Toggle preventDefault
36+
</button>
37+
</p>
1038

1139
@code {
1240
private int currentCount = 0;
41+
private bool showElements = true;
42+
private bool preventDefault = true;
1343

1444
private void IncrementCount()
1545
{
1646
currentCount++;
1747
}
48+
49+
void ToggleShow()
50+
{
51+
showElements = !showElements;
52+
StateHasChanged();
53+
}
54+
55+
void TogglePreventDefault()
56+
{
57+
preventDefault = !preventDefault;
58+
StateHasChanged();
59+
}
1860
}

src/Components/Web.JS/src/Rendering/Events/EventDelegator.ts

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ export class EventDelegator {
121121
for (const handlerInfo of infosForElement.enumerateHandlers()) {
122122
this.eventInfoStore.remove(handlerInfo.eventHandlerId);
123123
}
124+
125+
for (const eventName of infosForElement.enumeratedEventNamesForEnabledFlags()) {
126+
this.eventInfoStore.decrementCountByEventName(eventName);
127+
}
128+
124129
delete element[this.eventsCollectionKey];
125130
}
126131
}
@@ -136,11 +141,23 @@ export class EventDelegator {
136141
public setStopPropagation(element: Element, eventName: string, value: boolean): void {
137142
const infoForElement = this.getEventHandlerInfosForElement(element, true)!;
138143
infoForElement.stopPropagation(eventName, value);
144+
145+
if (value) {
146+
this.eventInfoStore.addGlobalListener(eventName);
147+
} else {
148+
this.eventInfoStore.decrementCountByEventName(eventName);
149+
}
139150
}
140151

141152
public setPreventDefault(element: Element, eventName: string, value: boolean): void {
142153
const infoForElement = this.getEventHandlerInfosForElement(element, true)!;
143154
infoForElement.preventDefault(eventName, value);
155+
156+
if (value) {
157+
this.eventInfoStore.addGlobalListener(eventName);
158+
} else {
159+
this.eventInfoStore.decrementCountByEventName(eventName);
160+
}
144161
}
145162

146163
private onGlobalEvent(evt: Event) {
@@ -298,16 +315,19 @@ class EventInfoStore {
298315

299316
// If this event name is an alias, update the global listener for the corresponding browser event
300317
const eventName = getBrowserEventName(info.eventName);
301-
302-
if (--this.countByEventName[eventName] === 0) {
303-
delete this.countByEventName[eventName];
304-
document.removeEventListener(eventName, this.globalListener);
305-
}
318+
this.decrementCountByEventName(eventName);
306319
}
307320

308321
return info;
309322
}
310323

324+
public decrementCountByEventName(eventName: string) {
325+
if (--this.countByEventName[eventName] === 0) {
326+
delete this.countByEventName[eventName];
327+
document.removeEventListener(eventName, this.globalListener);
328+
}
329+
}
330+
311331
private handleEventNameAliasAdded(aliasEventName, browserEventName) {
312332
// If an event name alias gets registered later, we need to update the global listener
313333
// registrations to match. This makes it equivalent to the alias having been registered
@@ -346,6 +366,20 @@ class EventHandlerInfosForElement {
346366
}
347367
}
348368

369+
public *enumeratedEventNamesForEnabledFlags(): IterableIterator<string> {
370+
for (const eventName in this.preventDefaultFlags) {
371+
if (this.preventDefaultFlags[eventName] === true) {
372+
yield eventName;
373+
}
374+
}
375+
376+
for (const eventName in this.stopPropagationFlags) {
377+
if (this.stopPropagationFlags[eventName] === true) {
378+
yield eventName;
379+
}
380+
}
381+
}
382+
349383
public getHandler(eventName: string): EventHandlerInfo | null {
350384
return Object.prototype.hasOwnProperty.call(this.handlers, eventName) ? this.handlers[eventName] : null;
351385
}

0 commit comments

Comments
 (0)