Skip to content
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
1 change: 1 addition & 0 deletions ReactWindows/ReactNative.Net46/ReactNative.Net46.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
<HintPath>$(SolutionDir)\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Windows" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using ReactNative.UIManager;
using ReactNative.Reflection;
using ReactNative.UIManager;
using ReactNative.UIManager.Annotations;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
Expand Down Expand Up @@ -40,6 +43,33 @@ public void SetColor(TextBlock view, uint? color)
: null;
}

/// <summary>
/// Sets the TextDecorationLine for the node.
/// </summary>
/// <param name="view">The view.</param>
/// <param name="textDecorationLineValue">The TextDecorationLine value.</param>
[ReactProp(ViewProps.TextDecorationLine)]
public void SetTextDecorationLine(TextBlock view, string textDecorationLineValue)
{
var textDecorationLine = EnumHelpers.ParseNullable<TextDecorationLine>(textDecorationLineValue) ?? TextDecorationLine.None;
switch (textDecorationLine)
{
case TextDecorationLine.Underline:
view.TextDecorations = TextDecorations.Underline;
break;
case TextDecorationLine.LineThrough:
view.TextDecorations = TextDecorations.Strikethrough;
break;
case TextDecorationLine.UnderlineLineThrough:
view.TextDecorations = new TextDecorationCollection(TextDecorations.Underline.Concat(TextDecorations.Strikethrough));
break;
case TextDecorationLine.None:
default:
view.TextDecorations = null;
break;
}
}

/// <summary>
/// Sets whether or not the text is selectable.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Views\TextInput\ReactTextInputSelectionEvent.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Views\TextInput\ReactTextInputShadowNode.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Views\TextInput\ReactTextInputSubmitEditingEvent.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Views\Text\TextDecorationLine.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Views\ViewManagersPropertyCache.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Views\View\ReactViewManager.cs" />
</ItemGroup>
Expand Down
32 changes: 27 additions & 5 deletions ReactWindows/ReactNative.Shared/Reflection/EnumHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using static System.FormattableString;

namespace ReactNative.Reflection
Expand All @@ -15,11 +17,7 @@ public static T Parse<T>(string value)
{
var lookup = s_enumCache.GetOrAdd(
typeof(T),
type => Enum.GetValues(type)
.Cast<object>()
.ToDictionary(
e => Normalize(e.ToString()),
e => e));
type => EnumToDictionary(type));

var result = default(object);
if (!lookup.TryGetValue(Normalize(value), out result))
Expand All @@ -41,6 +39,30 @@ public static T Parse<T>(string value)
return Parse<T>(value);
}

private static Dictionary<string, object> EnumToDictionary(Type type)
{
var result = new Dictionary<string, object>();

var names = Enum.GetNames(type);
var values = Enum.GetValues(type);

for (int i = 0; i < values.Length; ++i)
{
string name = names[i];
object value = values.GetValue(i);

result.Add(Normalize(name), value);

var enumMemberAttribute = type.GetField(name).GetCustomAttribute(typeof(EnumMemberAttribute), false);
if (enumMemberAttribute != null)
{
result.Add(Normalize(((EnumMemberAttribute)enumMemberAttribute).Value), value);
}
}

return result;
}

private static string Normalize(string value)
{
return value.ToLowerInvariant().Replace("-", "");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using ReactNative.UIManager;
using ReactNative.Reflection;
using ReactNative.UIManager;
using ReactNative.UIManager.Annotations;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

#if WINDOWS_UWP
using Windows.UI.Xaml;
using Windows.UI.Xaml.Documents;
Expand Down Expand Up @@ -55,6 +59,36 @@ public void SetColor(Span view, uint? color)
: null;
}

#if !WINDOWS_UWP
/// <summary>
/// Sets the TextDecorationLine for the node.
/// </summary>
/// <param name="view">The view.</param>
/// <param name="textDecorationLineValue">The TextDecorationLine value.</param>
[ReactProp(ViewProps.TextDecorationLine)]
public void SetTextDecorationLine(Span view, string textDecorationLineValue)
{
var textDecorationLine = EnumHelpers.ParseNullable<TextDecorationLine>(textDecorationLineValue) ?? TextDecorationLine.None;

switch (textDecorationLine)
{
case TextDecorationLine.Underline:
view.TextDecorations = TextDecorations.Underline;
break;
case TextDecorationLine.LineThrough:
view.TextDecorations = TextDecorations.Strikethrough;
break;
case TextDecorationLine.UnderlineLineThrough:
view.TextDecorations = new TextDecorationCollection(TextDecorations.Underline.Concat(TextDecorations.Strikethrough));
break;
case TextDecorationLine.None:
default:
view.TextDecorations = null;
break;
}
}
#endif

/// <summary>
/// Adds a child at the given index.
/// </summary>
Expand Down
28 changes: 28 additions & 0 deletions ReactWindows/ReactNative.Shared/Views/Text/TextDecorationLine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Runtime.Serialization;

namespace ReactNative.Views.Text
{
/// <summary>
/// TextDecorationLine values.
/// </summary>
public enum TextDecorationLine
{
/// <summary>
/// Text has no line decoration.
/// </summary>
None,
/// <summary>
/// Text is Underlined.
/// </summary>
Underline,
/// <summary>
/// Text is Stroke out.
/// </summary>
LineThrough,
/// <summary>
/// Text is both Underlined and Stroke out.
/// </summary>
[EnumMember(Value = "underline line-through")]
UnderlineLineThrough

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is cool, this is compatible with the existing EnumHelpers class? We should re-write all the other enums to use this where possible. Ideally we could get rid of that reflection hack.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually don't need this enum, you can just as easily switch case on the string itself.


In reply to: 104831419 [](ancestors = 104831419)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That will avoid the dependency on System.Runtime.Serialization, and avoid the reflection driven changes to EnumHelpers


In reply to: 104832645 [](ancestors = 104832645,104831419)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally vote for enum instead of string, if there is a limited number of variants, because it
makes corresponding code strongly-typed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I tend to agree that strong typing is usually good, I don't like that we have to add yet another dependency and pay an attribute reflection penalty for all enums across the framework just to support this strong typing.


In reply to: 105130501 [](ancestors = 105130501)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When making decision on changing EnumHelpers I was looking onto "textAlign". Logically it is same as "textDecorationLine" and they both should be treated in same way. But "textDecorationLine" contains single value with space in it, which makes it impossible to use existing approach. So, either it must be an exceptional enum, treated differently (How many such enums can we possibly have?) or the approach should be changed. I've chosen the latter.
I am not against "switch" so if you insist, that's ok. But, please note, Reflection does not have "that" bad impact on performance if it happens once. Yes, if we have 100 000 of enums, then we will see the difference, but currently we have ~20 total and maybe it will grow up to 100 or 200 at most.

}
}