Commit Graph

21 Commits

Author SHA1 Message Date
Ryan Nowak ed06d7b12e Rough cut at async events 2018-04-26 13:31:28 -07:00
Steve Sanderson 4cbf6cc64b Enable GenerateDocumentationFile. Add/fix XML docs. 2018-04-13 16:57:09 +01:00
Ryan Nowak 8485e2ea10 Add support for Action event handlers
This change adds `Action` to the set of types that have an overload on
RenderTreeBuilder. Additionally, we special case `Action` in the runtime
because passing the event args via DynamicInvoke() would throw.

Finally, reverted some of the clutter introduced by the first pass of
the event handler feature.
2018-04-11 07:36:05 -07:00
Ryan Nowak df13669362 Improvements for delegate types (#516)
* Improve support for more types of event handlers

Improves support for for other types of event handlers with eventargs
types derived from UIEventArgs. Additionally fleshes out the set of
event handler types.

This change improves support for using more specific event handler types
like:

```
<button onclick="@Clicked" />

@functions {
    public void Clicked(UIMouseEventArgs e) { ... }
}
```

And:
```
builder.AddAttribute(12, "onkeypressed", KeyPressed);

...

void KeyPressed(UIKeyboardEventArgs e) { ... }

```

In particular what got better is:
- overload resolution for the AddAttribute method
- performance of different cases for AddAttribute

-----

The runtime now treats delegates as one of three types:
- arbitrary delegate: not attached to DOM events, not tracked by
renderer
- UIEventHandler: can attach to DOM events, tracked by renderer, first
class in IHandleEvents
- UIEventHandler-like: can attach to DOM events, tracked by renderer,
requires some special runtime support.

The set of overloads on AddAttribute has been tuned with a few specific
cases in mind.

Lambda expressions in an attribute will be inferred as UIEventHandler
unless the compiler does something more specific. So for instance,
passing a lambda as an attribute value for a component, where the
component doesn't define a matching attribute, will always be inferred
as UIEventHandler.

We now support method-group to delegate conversion for methods that
accept a derived UIEventArgs type. This means you can use a signature
like `void KeyPressed(UIKeyboardEventArgs e)` without any compiler
magic, and this will work in the runtime as long as the event type
produced by the runtime matches.

We also allow user-defined UIEventArgs-derived types. There's a pattern
for this and it requires defining an extension method and delegate type.

The method-group to delegate conversion part required some doing. It
doesn't play well with generics (Action<T> where T : UIEventArgs)
doesn't work at all. Adding more actual overloads (as opposed to
extensions) would cause lambda cases we want to work to be ambiguous.

----

The performance win here is to remove the need for a 'wrapper' delegate
created by the event handler tag helper code. This wrapper is now
created by the runtime, but only *after* we have checked the frame for
changes. This requires more heavy lifting in the runtime, but has the
advantage of producing no-op diffs as often as possible.

You will still get some inefficient behavior if your component uses a
capturing lambda in an event handler, so don't do that.

* Add selenium logs to test output

* Minor feedback

* WIP
2018-04-09 13:21:12 -07:00
Ryan Nowak d097190824 Add support for conditional attributes
Adds conditional attributes for HTML elements.

This means that an attribute with a 'false' .NET bool value or a null
.NET value of another type will not be rendered in the HTML.
2018-04-03 14:06:48 -07:00
Ryan Nowak 57a04fb178 Adopt more of Razor Exensibility
Removes some workarounds and uses Razor extensibility in a few more
places.

_ViewImports now works in VS
2018-03-14 11:23:40 +00:00
Steve Sanderson 3e30655ea4 Low-level NavLink implementation 2018-02-22 15:03:49 +00:00
Steve Sanderson 1a31634b70 Capture component child content as a RenderFragment parameter. 2018-02-22 11:07:03 +00:00
Steve Sanderson ad2c63ca37 Make OpenRegion/CloseRegion not public because they are only to support AddContent(seq, fragment) 2018-02-16 10:10:12 +00:00
Steve Sanderson 41aae0b7e6 Add ability to append RenderFragment into a RenderTreeBuilder 2018-02-16 10:10:11 +00:00
Steve Sanderson 1ac5ee25c1 Rename RenderTreeBuilder's AddText to AddContent, since it will be used for other types too 2018-02-16 10:10:08 +00:00
Steve Sanderson acc5b9461b Add ability to add component frame using runtime type object instead of generic param 2018-02-16 10:10:07 +00:00
Steve Sanderson 2da17602ed Support "Region" frames in JS-side code
They only appear in a prepended subtree, because the .NET-side diffing
code resolves them out if they are top-level to any given edit
2018-02-14 23:41:25 +00:00
Steve Sanderson a9822216f1 Add the concept of a "Region" render tree frame 2018-02-14 23:41:24 +00:00
Ryan Nowak 043e623d5b Split Razor extensibility into its own assembly
This functionality will need to cross-compile to desktop framework
(net461) so that we can use it in VS. VS doesn't yet have netstandard2.0
support.
2018-02-14 14:08:14 -08:00
Steve Sanderson 33932f41fc Replace "DescendantsEndIndex" concept with "SubtreeLength"
In other words, use relative addressing so that frame data is
independent of its position in the array
2018-02-07 10:27:32 +00:00
Steve Sanderson 93f17219ea Rename OpenComponentElement -> OpenComponent for consistency 2018-02-05 00:19:44 +00:00
Steve Sanderson 1fda744770 Make RenderTreeFrame properly readonly to allow more pass-by-ref cases 2018-02-05 00:16:08 +00:00
Steve Sanderson f1332919bc Rename RenderTreeNode -> RenderTreeFrame (and correspondingly, "node" ->
"frame" everywhere)
2018-02-04 22:21:29 +00:00
Steve Sanderson 3940ca8b60 For components, allow attribute values to be arbitrary objects 2018-01-26 09:54:35 -08:00
Steve Sanderson 0aa164073d Rename Microsoft.Blazor.* -> Microsoft.AspNetCore.Blazor.* everywhere 2018-01-24 15:48:38 -08:00