|
|
@@ -3,6 +3,7 @@ import { EventDelegator } from './EventDelegator';
|
|
|
import { EventForDotNet, UIEventArgs } from './EventForDotNet';
|
|
|
import { LogicalElement, PermutationListEntry, toLogicalElement, insertLogicalChild, removeLogicalChild, getLogicalParent, getLogicalChild, createAndInsertLogicalContainer, isSvgElement, getLogicalChildrenArray, getLogicalSiblingEnd, permuteLogicalChildren, getClosestDomElement } from './LogicalElements';
|
|
|
import { applyCaptureIdToElement } from './ElementReferenceCapture';
|
|
|
+import { EventFieldInfo } from './EventFieldInfo';
|
|
|
const selectValuePropname = '_blazorSelectValue';
|
|
|
const sharedTemplateElemForParsing = document.createElement('template');
|
|
|
const sharedSvgElemForParsing = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
|
|
@@ -18,8 +19,8 @@ export class BrowserRenderer {
|
|
|
|
|
|
public constructor(browserRendererId: number) {
|
|
|
this.browserRendererId = browserRendererId;
|
|
|
- this.eventDelegator = new EventDelegator((event, eventHandlerId, eventArgs) => {
|
|
|
- raiseEvent(event, this.browserRendererId, eventHandlerId, eventArgs);
|
|
|
+ this.eventDelegator = new EventDelegator((event, eventHandlerId, eventArgs, eventFieldInfo) => {
|
|
|
+ raiseEvent(event, this.browserRendererId, eventHandlerId, eventArgs, eventFieldInfo);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
@@ -50,7 +51,7 @@ export class BrowserRenderer {
|
|
|
const ownerDocument = getClosestDomElement(element).ownerDocument;
|
|
|
const activeElementBefore = ownerDocument && ownerDocument.activeElement;
|
|
|
|
|
|
- this.applyEdits(batch, element, 0, edits, referenceFrames);
|
|
|
+ this.applyEdits(batch, componentId, element, 0, edits, referenceFrames);
|
|
|
|
|
|
// Try to restore focus in case it was lost due to an element move
|
|
|
if ((activeElementBefore instanceof HTMLElement) && ownerDocument && ownerDocument.activeElement !== activeElementBefore) {
|
|
|
@@ -70,7 +71,7 @@ export class BrowserRenderer {
|
|
|
this.childComponentLocations[componentId] = element;
|
|
|
}
|
|
|
|
|
|
- private applyEdits(batch: RenderBatch, parent: LogicalElement, childIndex: number, edits: ArraySegment<RenderTreeEdit>, referenceFrames: ArrayValues<RenderTreeFrame>) {
|
|
|
+ private applyEdits(batch: RenderBatch, componentId: number, parent: LogicalElement, childIndex: number, edits: ArraySegment<RenderTreeEdit>, referenceFrames: ArrayValues<RenderTreeFrame>) {
|
|
|
let currentDepth = 0;
|
|
|
let childIndexAtCurrentDepth = childIndex;
|
|
|
let permutationList: PermutationListEntry[] | undefined;
|
|
|
@@ -91,7 +92,7 @@ export class BrowserRenderer {
|
|
|
const frameIndex = editReader.newTreeIndex(edit);
|
|
|
const frame = batch.referenceFramesEntry(referenceFrames, frameIndex);
|
|
|
const siblingIndex = editReader.siblingIndex(edit);
|
|
|
- this.insertFrame(batch, parent, childIndexAtCurrentDepth + siblingIndex, referenceFrames, frame, frameIndex);
|
|
|
+ this.insertFrame(batch, componentId, parent, childIndexAtCurrentDepth + siblingIndex, referenceFrames, frame, frameIndex);
|
|
|
break;
|
|
|
}
|
|
|
case EditType.removeFrame: {
|
|
|
@@ -105,7 +106,7 @@ export class BrowserRenderer {
|
|
|
const siblingIndex = editReader.siblingIndex(edit);
|
|
|
const element = getLogicalChild(parent, childIndexAtCurrentDepth + siblingIndex);
|
|
|
if (element instanceof Element) {
|
|
|
- this.applyAttribute(batch, element, frame);
|
|
|
+ this.applyAttribute(batch, componentId, element, frame);
|
|
|
} else {
|
|
|
throw new Error('Cannot set attribute on non-element child');
|
|
|
}
|
|
|
@@ -182,12 +183,12 @@ export class BrowserRenderer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private insertFrame(batch: RenderBatch, parent: LogicalElement, childIndex: number, frames: ArrayValues<RenderTreeFrame>, frame: RenderTreeFrame, frameIndex: number): number {
|
|
|
+ private insertFrame(batch: RenderBatch, componentId: number, parent: LogicalElement, childIndex: number, frames: ArrayValues<RenderTreeFrame>, frame: RenderTreeFrame, frameIndex: number): number {
|
|
|
const frameReader = batch.frameReader;
|
|
|
const frameType = frameReader.frameType(frame);
|
|
|
switch (frameType) {
|
|
|
case FrameType.element:
|
|
|
- this.insertElement(batch, parent, childIndex, frames, frame, frameIndex);
|
|
|
+ this.insertElement(batch, componentId, parent, childIndex, frames, frame, frameIndex);
|
|
|
return 1;
|
|
|
case FrameType.text:
|
|
|
this.insertText(batch, parent, childIndex, frame);
|
|
|
@@ -198,7 +199,7 @@ export class BrowserRenderer {
|
|
|
this.insertComponent(batch, parent, childIndex, frame);
|
|
|
return 1;
|
|
|
case FrameType.region:
|
|
|
- return this.insertFrameRange(batch, parent, childIndex, frames, frameIndex + 1, frameIndex + frameReader.subtreeLength(frame));
|
|
|
+ return this.insertFrameRange(batch, componentId, parent, childIndex, frames, frameIndex + 1, frameIndex + frameReader.subtreeLength(frame));
|
|
|
case FrameType.elementReferenceCapture:
|
|
|
if (parent instanceof Element) {
|
|
|
applyCaptureIdToElement(parent, frameReader.elementReferenceCaptureId(frame)!);
|
|
|
@@ -215,7 +216,7 @@ export class BrowserRenderer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private insertElement(batch: RenderBatch, parent: LogicalElement, childIndex: number, frames: ArrayValues<RenderTreeFrame>, frame: RenderTreeFrame, frameIndex: number) {
|
|
|
+ private insertElement(batch: RenderBatch, componentId: number, parent: LogicalElement, childIndex: number, frames: ArrayValues<RenderTreeFrame>, frame: RenderTreeFrame, frameIndex: number) {
|
|
|
const frameReader = batch.frameReader;
|
|
|
const tagName = frameReader.elementName(frame)!;
|
|
|
const newDomElementRaw = tagName === 'svg' || isSvgElement(parent) ?
|
|
|
@@ -229,11 +230,11 @@ export class BrowserRenderer {
|
|
|
for (let descendantIndex = frameIndex + 1; descendantIndex < descendantsEndIndexExcl; descendantIndex++) {
|
|
|
const descendantFrame = batch.referenceFramesEntry(frames, descendantIndex);
|
|
|
if (frameReader.frameType(descendantFrame) === FrameType.attribute) {
|
|
|
- this.applyAttribute(batch, newDomElementRaw, descendantFrame);
|
|
|
+ this.applyAttribute(batch, componentId, newDomElementRaw, descendantFrame);
|
|
|
} else {
|
|
|
// As soon as we see a non-attribute child, all the subsequent child frames are
|
|
|
// not attributes, so bail out and insert the remnants recursively
|
|
|
- this.insertFrameRange(batch, newElement, 0, frames, descendantIndex, descendantsEndIndexExcl);
|
|
|
+ this.insertFrameRange(batch, componentId, newElement, 0, frames, descendantIndex, descendantsEndIndexExcl);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
@@ -265,7 +266,7 @@ export class BrowserRenderer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private applyAttribute(batch: RenderBatch, toDomElement: Element, attributeFrame: RenderTreeFrame) {
|
|
|
+ private applyAttribute(batch: RenderBatch, componentId: number, toDomElement: Element, attributeFrame: RenderTreeFrame) {
|
|
|
const frameReader = batch.frameReader;
|
|
|
const attributeName = frameReader.attributeName(attributeFrame)!;
|
|
|
const browserRendererId = this.browserRendererId;
|
|
|
@@ -277,7 +278,7 @@ export class BrowserRenderer {
|
|
|
if (firstTwoChars !== 'on' || !eventName) {
|
|
|
throw new Error(`Attribute has nonzero event handler ID, but attribute name '${attributeName}' does not start with 'on'.`);
|
|
|
}
|
|
|
- this.eventDelegator.setListener(toDomElement, eventName, eventHandlerId);
|
|
|
+ this.eventDelegator.setListener(toDomElement, eventName, eventHandlerId, componentId);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
@@ -352,11 +353,11 @@ export class BrowserRenderer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private insertFrameRange(batch: RenderBatch, parent: LogicalElement, childIndex: number, frames: ArrayValues<RenderTreeFrame>, startIndex: number, endIndexExcl: number): number {
|
|
|
+ private insertFrameRange(batch: RenderBatch, componentId: number, parent: LogicalElement, childIndex: number, frames: ArrayValues<RenderTreeFrame>, startIndex: number, endIndexExcl: number): number {
|
|
|
const origChildIndex = childIndex;
|
|
|
for (let index = startIndex; index < endIndexExcl; index++) {
|
|
|
const frame = batch.referenceFramesEntry(frames, index);
|
|
|
- const numChildrenInserted = this.insertFrame(batch, parent, childIndex, frames, frame, index);
|
|
|
+ const numChildrenInserted = this.insertFrame(batch, componentId, parent, childIndex, frames, frame, index);
|
|
|
childIndex += numChildrenInserted;
|
|
|
|
|
|
// Skip over any descendants, since they are already dealt with recursively
|
|
|
@@ -397,7 +398,7 @@ function countDescendantFrames(batch: RenderBatch, frame: RenderTreeFrame): numb
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-function raiseEvent(event: Event, browserRendererId: number, eventHandlerId: number, eventArgs: EventForDotNet<UIEventArgs>) {
|
|
|
+function raiseEvent(event: Event, browserRendererId: number, eventHandlerId: number, eventArgs: EventForDotNet<UIEventArgs>, eventFieldInfo: EventFieldInfo | null) {
|
|
|
if (preventDefaultEvents[event.type]) {
|
|
|
event.preventDefault();
|
|
|
}
|
|
|
@@ -406,6 +407,7 @@ function raiseEvent(event: Event, browserRendererId: number, eventHandlerId: num
|
|
|
browserRendererId,
|
|
|
eventHandlerId,
|
|
|
eventArgsType: eventArgs.type,
|
|
|
+ eventFieldInfo: eventFieldInfo,
|
|
|
};
|
|
|
|
|
|
return DotNet.invokeMethodAsync(
|