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

Move in changes for 1.2.4 release #3565

Merged
merged 20 commits into from
Nov 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e2fd25f
[UWP] Add accessible names to all action buttons (#3528)
paulcam206 Oct 21, 2019
ddcc7af
[.NET] Updated obsolete messages (#3529)
jwoo-msft Oct 22, 2019
19057e0
Add validation for properly rendered columns (#3471)
almedina-ms Sep 23, 2019
db6fab6
[.NET] Parse Context Update (#3548)
jwoo-msft Oct 30, 2019
834c227
.Net Concurrency (#3556)
jwoo-msft Nov 1, 2019
0e49991
[.NET] Added missing pieces from previous commit
jwoo-msft Nov 1, 2019
dc5c4c5
[iOS] Added Custom Parsing and allowed signal to be passed to host ap…
jwoo-msft Oct 24, 2019
984c5c7
[iOS][Sample App]Updated custom image renderer to handle toggle visib…
jwoo-msft Oct 25, 2019
1ab18d8
[UWP] Fix circular reference in ImageOpened lambda for Auto sized ima…
Oct 9, 2019
32fe148
[UWP] Fix cirucular reference in element tag (#3496)
Sep 27, 2019
e656484
updated version info
jwoo-msft Nov 1, 2019
4de189b
Release: Updating custom.props to 1.2.4
shalinijoshi19 Nov 1, 2019
a0d240c
[UWP] Use custom button to show OpenUrl actions as links (#3555)
paulcam206 Nov 1, 2019
526f902
[iOS] allows default text renderers to be used in their custom versio…
jwoo-msft Oct 1, 2019
605f1c5
[UWP] Update PerfApp test signing cert
paulcam206 Nov 4, 2019
6fccd7d
[UWP] Move accessibility changes from ActionHelpers to XamlBuilder
paulcam206 Nov 4, 2019
51b9389
Revert "fix xml serialization (#3455)"
shalinijoshi19 Nov 4, 2019
8801606
Bad merge with the last revert
shalinijoshi19 Nov 4, 2019
5878c7c
Merge branch 'paulcam/release-1.2.4' of https://github.com/microsoft/…
shalinijoshi19 Nov 4, 2019
69a16d1
fixed bad merge
jwoo-msft Nov 4, 2019
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
2 changes: 1 addition & 1 deletion custom.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<VersionMajor>1</VersionMajor>
<VersionMinor>2</VersionMinor>
<!-- The nuget package version should be incremented when we produce QFEs -->
<NuGetPackVersion>1.2.3</NuGetPackVersion>
<NuGetPackVersion>1.2.4</NuGetPackVersion>
<VersionInfoProductName>AdaptiveCards</VersionInfoProductName>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -60,83 +60,87 @@ public static FrameworkElement Render(AdaptiveColumnSet columnSet, AdaptiveRende

FrameworkElement uiContainer = context.Render(column);

TagContent tag = null;

// Add vertical Separator
if (uiColumnSet.ColumnDefinitions.Count > 0 && (column.Separator || column.Spacing != AdaptiveSpacing.None))
// If the column couldn't be rendered and the fallback is 'drop'
if (uiContainer != null)
{
var uiSep = new Grid();
uiSep.Style = context.GetStyle($"Adaptive.VerticalSeparator");
TagContent tag = null;

uiSep.VerticalAlignment = VerticalAlignment.Stretch;
// Add vertical Separator
if (uiColumnSet.ColumnDefinitions.Count > 0 && (column.Separator || column.Spacing != AdaptiveSpacing.None))
{
var uiSep = new Grid();
uiSep.Style = context.GetStyle($"Adaptive.VerticalSeparator");

int spacing = context.Config.GetSpacing(column.Spacing);
uiSep.Margin = new Thickness(spacing / 2.0, 0, spacing / 2.0, 0);
uiSep.VerticalAlignment = VerticalAlignment.Stretch;

uiSep.Width = context.Config.Separator.LineThickness;
if (column.Separator && context.Config.Separator.LineColor != null)
{
uiSep.Background = context.GetColorBrush(context.Config.Separator.LineColor);
}
int spacing = context.Config.GetSpacing(column.Spacing);
uiSep.Margin = new Thickness(spacing / 2.0, 0, spacing / 2.0, 0);

tag = new TagContent(uiSep, uiColumnSet);
uiSep.Width = context.Config.Separator.LineThickness;
if (column.Separator && context.Config.Separator.LineColor != null)
{
uiSep.Background = context.GetColorBrush(context.Config.Separator.LineColor);
}

uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
Grid.SetColumn(uiSep, uiColumnSet.ColumnDefinitions.Count - 1);
uiColumnSet.Children.Add(uiSep);
}
else
{
tag = new TagContent(null, uiColumnSet);
}
tag = new TagContent(uiSep, uiColumnSet);

uiColumnSet.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
Grid.SetColumn(uiSep, uiColumnSet.ColumnDefinitions.Count - 1);
uiColumnSet.Children.Add(uiSep);
}
else
{
tag = new TagContent(null, uiColumnSet);
}

// do some sizing magic using the magic GridUnitType.Star
var width = column.Width?.ToLower();
if (string.IsNullOrEmpty(width))
// do some sizing magic using the magic GridUnitType.Star
var width = column.Width?.ToLower();
if (string.IsNullOrEmpty(width))
#pragma warning disable CS0618 // Type or member is obsolete
width = column.Size?.ToLower();
width = column.Size?.ToLower();
#pragma warning restore CS0618 // Type or member is obsolete

ColumnDefinition columnDefinition = null;
ColumnDefinition columnDefinition = null;

if (width == null || width == AdaptiveColumnWidth.Stretch.ToLower())
{
columnDefinition = new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) };
}
else if (width == AdaptiveColumnWidth.Auto.ToLower())
{
columnDefinition = new ColumnDefinition() { Width = GridLength.Auto };
}
else
{
if (double.TryParse(width, out double val) && val >= 0)
if (width == null || width == AdaptiveColumnWidth.Stretch.ToLower())
{
// Weighted proportion (number only)
columnDefinition = new ColumnDefinition() { Width = new GridLength(val, GridUnitType.Star) };
columnDefinition = new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) };
}
else if (width.EndsWith("px") && double.TryParse(width.Substring(0, width.Length - 2), out double pxVal) && pxVal >= 0)
else if (width == AdaptiveColumnWidth.Auto.ToLower())
{
// Exact pixel (number followed by "px")
columnDefinition = new ColumnDefinition() { Width = new GridLength((int)pxVal, GridUnitType.Pixel) };
columnDefinition = new ColumnDefinition() { Width = GridLength.Auto };
}
else
{
columnDefinition = new ColumnDefinition() { Width = GridLength.Auto };
if (double.TryParse(width, out double val) && val >= 0)
{
// Weighted proportion (number only)
columnDefinition = new ColumnDefinition() { Width = new GridLength(val, GridUnitType.Star) };
}
else if (width.EndsWith("px") && double.TryParse(width.Substring(0, width.Length - 2), out double pxVal) && pxVal >= 0)
{
// Exact pixel (number followed by "px")
columnDefinition = new ColumnDefinition() { Width = new GridLength((int)pxVal, GridUnitType.Pixel) };
}
else
{
columnDefinition = new ColumnDefinition() { Width = GridLength.Auto };
}
}
}

// Store the column definition in the tag so we can toggle the visibility later
tag.ColumnDefinition = columnDefinition;
tag.ViewIndex = uiColumnSet.ColumnDefinitions.Count;
// Store the column definition in the tag so we can toggle the visibility later
tag.ColumnDefinition = columnDefinition;
tag.ViewIndex = uiColumnSet.ColumnDefinitions.Count;

uiColumnSet.ColumnDefinitions.Add(columnDefinition);
uiColumnSet.ColumnDefinitions.Add(columnDefinition);

uiContainer.Tag = tag;

Grid.SetColumn(uiContainer, uiColumnSet.ColumnDefinitions.Count - 1);
uiColumnSet.Children.Add(uiContainer);
uiContainer.Tag = tag;

context.SetVisibility(uiContainer, column.IsVisible, tag);
Grid.SetColumn(uiContainer, uiColumnSet.ColumnDefinitions.Count - 1);
uiColumnSet.Children.Add(uiContainer);

context.SetVisibility(uiContainer, column.IsVisible, tag);
}
}

context.ResetSeparatorVisibilityInsideContainer(uiColumnSet);
Expand Down
1 change: 0 additions & 1 deletion source/dotnet/Library/AdaptiveCards/AdaptiveActionSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public class AdaptiveActionSet : AdaptiveElement
[XmlElement(typeof(AdaptiveShowCardAction))]
[XmlElement(typeof(AdaptiveSubmitAction))]
[XmlElement(typeof(AdaptiveToggleVisibilityAction))]
[XmlElement(typeof(AdaptiveUnknownAction))]
#endif
public List<AdaptiveAction> Actions { get; set; } = new List<AdaptiveAction>();
}
Expand Down
30 changes: 23 additions & 7 deletions source/dotnet/Library/AdaptiveCards/AdaptiveCard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ public AdaptiveCard(AdaptiveSchemaVersion schemaVersion)
[JsonConverter(typeof(StringSizeWithUnitConverter), true)]
[JsonProperty(Order = -4, DefaultValueHandling = DefaultValueHandling.Ignore)]
#if !NETSTANDARD1_3
[XmlElement]
[XmlElement(typeof(AdaptiveHeight))]
#endif
public AdaptiveHeight Height { get; set; } = new AdaptiveHeight(AdaptiveHeightType.Auto);
[DefaultValue(typeof(AdaptiveHeight), "auto")]
public AdaptiveHeight Height { get; set; }

/// <summary>
/// Explicit card minimum height in pixels
Expand All @@ -145,7 +146,6 @@ public AdaptiveCard(AdaptiveSchemaVersion schemaVersion)
[JsonConverter(typeof(IgnoreEmptyItemsConverter<AdaptiveElement>))]
#if !NETSTANDARD1_3
[XmlElement(typeof(AdaptiveTextBlock))]
[XmlElement(typeof(AdaptiveRichTextBlock))]
[XmlElement(typeof(AdaptiveImage))]
[XmlElement(typeof(AdaptiveContainer))]
[XmlElement(typeof(AdaptiveColumnSet))]
Expand All @@ -159,7 +159,6 @@ public AdaptiveCard(AdaptiveSchemaVersion schemaVersion)
[XmlElement(typeof(AdaptiveChoiceSetInput))]
[XmlElement(typeof(AdaptiveMedia))]
[XmlElement(typeof(AdaptiveActionSet))]
[XmlElement(typeof(AdaptiveUnknownElement))]
#endif
public List<AdaptiveElement> Body { get; set; } = new List<AdaptiveElement>();

Expand All @@ -175,7 +174,6 @@ public AdaptiveCard(AdaptiveSchemaVersion schemaVersion)
[XmlElement(typeof(AdaptiveShowCardAction))]
[XmlElement(typeof(AdaptiveSubmitAction))]
[XmlElement(typeof(AdaptiveToggleVisibilityAction))]
[XmlElement(typeof(AdaptiveUnknownAction))]
#endif
public List<AdaptiveAction> Actions { get; set; } = new List<AdaptiveAction>();

Expand Down Expand Up @@ -215,7 +213,25 @@ public bool ShouldSerializeJsonSchema()
[DefaultValue(null)]
public AdaptiveAction SelectAction { get; set; }

public bool ShouldSerializeHeight() => this.Height?.ShouldSerializeAdaptiveHeight() == true;
public bool ShouldSerializeHeight()
{
if (Height == AdaptiveHeight.Auto)
{
return false;
}
if (Height.HeightType == AdaptiveHeightType.Pixel)
{
if (!Height.Unit.HasValue)
{
return false;
}
if (Height.Unit.Value == 0)
{
return false;
}
}
return true;
}

/// <summary>
/// Callback that will be invoked should a null or empty version string is encountered. The callback may return an alternate version to use for parsing.
Expand All @@ -238,7 +254,7 @@ public static AdaptiveCardParseResult FromJson(string json)
{
parseResult.Card = JsonConvert.DeserializeObject<AdaptiveCard>(json, new JsonSerializerSettings
{
ContractResolver = new WarningLoggingContractResolver(parseResult),
ContractResolver = new WarningLoggingContractResolver(parseResult, new ParseContext()),
Converters = { new StrictIntConverter() }
});
}
Expand Down
13 changes: 9 additions & 4 deletions source/dotnet/Library/AdaptiveCards/AdaptiveCardConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace AdaptiveCards
{
public class AdaptiveCardConverter : JsonConverter, ILogWarnings
public class AdaptiveCardConverter : AdaptiveTypedBaseElementConverter, ILogWarnings
{
public List<AdaptiveWarning> Warnings { get; set; } = new List<AdaptiveWarning>();

Expand Down Expand Up @@ -62,16 +62,21 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist

if (reader.Depth == 0)
{
// Needed for ID collision detection after fallback was introduced
ParseContext.Initialize();

ValidateJsonVersion(ref jObject);

if (new AdaptiveSchemaVersion(jObject.Value<string>("version")) > AdaptiveCard.KnownSchemaVersion)
{
return MakeFallbackTextCard(jObject);
}
}

/// this is needed when client calls JsonConvert.Deserializer method, we need this contract resolver,
/// so we can pass ParseContext
if (!(serializer.ContractResolver is WarningLoggingContractResolver))
{
serializer.ContractResolver = new WarningLoggingContractResolver(new AdaptiveCardParseResult(), new ParseContext());
}

var typedElementConverter = serializer.ContractResolver.ResolveContract(typeof(AdaptiveTypedElement)).Converter;

var card = (AdaptiveCard)typedElementConverter.ReadJson(jObject.CreateReader(), objectType, existingValue, serializer);
Expand Down
16 changes: 4 additions & 12 deletions source/dotnet/Library/AdaptiveCards/AdaptiveCollectionElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,24 @@ namespace AdaptiveCards
/// </summary>
public abstract class AdaptiveCollectionElement : AdaptiveElement
{

/// <summary>
/// The style in which the image is displayed.
/// </summary>
[JsonConverter(typeof(IgnoreNullEnumConverter<AdaptiveContainerStyle>), true)]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
#if !NETSTANDARD1_3
[XmlIgnore]
[XmlElement]
#endif
[DefaultValue(null)]
public AdaptiveContainerStyle? Style { get; set; }

#if !NETSTANDARD1_3
// Xml Serializer doesn't handle nullable value types, but this trick allows us to serialize only if non-null
[JsonIgnore]
[XmlAttribute("Style")]
[EditorBrowsable(EditorBrowsableState.Never)]
public AdaptiveContainerStyle StyleXml { get { return (Style.HasValue) ? Style.Value : AdaptiveContainerStyle.Default; } set { Style = value; } }
public bool ShouldSerializeStyleXml() => this.Style.HasValue;
#endif

/// <summary>
/// The content alignment for the element inside the container.
/// </summary>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
#if !NETSTANDARD1_3
[XmlAttribute]
[XmlElement]
#endif
[DefaultValue(typeof(AdaptiveVerticalContentAlignment), "top")]
public AdaptiveVerticalContentAlignment VerticalContentAlignment { get; set; }
Expand All @@ -61,7 +53,7 @@ public abstract class AdaptiveCollectionElement : AdaptiveElement
/// </summary>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
#if !NETSTANDARD1_3
[XmlAttribute]
[XmlElement]
#endif
[DefaultValue(false)]
public bool Bleed { get; set; }
Expand Down
2 changes: 0 additions & 2 deletions source/dotnet/Library/AdaptiveCards/AdaptiveContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public class AdaptiveContainer : AdaptiveCollectionElement
[JsonConverter(typeof(IgnoreEmptyItemsConverter<AdaptiveElement>))]
#if !NETSTANDARD1_3
[XmlElement(typeof(AdaptiveTextBlock))]
[XmlElement(typeof(AdaptiveRichTextBlock))]
[XmlElement(typeof(AdaptiveImage))]
[XmlElement(typeof(AdaptiveContainer))]
[XmlElement(typeof(AdaptiveColumnSet))]
Expand All @@ -48,7 +47,6 @@ public class AdaptiveContainer : AdaptiveCollectionElement
[XmlElement(typeof(AdaptiveToggleInput))]
[XmlElement(typeof(AdaptiveMedia))]
[XmlElement(typeof(AdaptiveActionSet))]
[XmlElement(typeof(AdaptiveUnknownElement))]
#endif
public List<AdaptiveElement> Items { get; set; } = new List<AdaptiveElement>();

Expand Down
27 changes: 23 additions & 4 deletions source/dotnet/Library/AdaptiveCards/AdaptiveElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,36 @@ public abstract class AdaptiveElement : AdaptiveTypedElement
[Obsolete("CardElement.Speak has been deprecated. Use AdaptiveCard.Speak", false)]
public string Speak { get; set; }

public bool ShouldSerializeHeight()
{
if (Height == AdaptiveHeight.Auto)
{
return false;
}
if (Height.HeightType == AdaptiveHeightType.Pixel)
{
if (!Height.Unit.HasValue)
{
return false;
}
if (Height.Unit.Value == 0)
{
return false;
}
}
return true;
}

/// <summary>
/// The amount of space the element should be separated from the previous element. Default value is <see cref="AdaptiveHeight.Default"/>.
/// </summary>
[JsonConverter(typeof(StringSizeWithUnitConverter), true)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
#if !NETSTANDARD1_3
[XmlElement]
[XmlElement(typeof(AdaptiveHeight))]
#endif
public AdaptiveHeight Height { get; set; } = new AdaptiveHeight(AdaptiveHeightType.Auto);

public bool ShouldSerializeHeight() => this.Height?.ShouldSerializeAdaptiveHeight() == true;
[DefaultValue(typeof(AdaptiveHeight), "auto")]
public AdaptiveHeight Height { get; set; }

/// <summary>
/// Indicates whether the element should be visible when the card has been rendered.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;

namespace AdaptiveCards
{
public class AdaptiveFallbackConverter : JsonConverter, ILogWarnings
public class AdaptiveFallbackConverter : AdaptiveTypedBaseElementConverter, ILogWarnings
{
public List<AdaptiveWarning> Warnings { get; set; } = new List<AdaptiveWarning>();

Expand Down Expand Up @@ -103,7 +105,7 @@ public override bool CanConvert(Type objectType)
return result;
}

public static AdaptiveFallbackElement ParseFallback(JToken fallbackJSON, JsonSerializer serializer, string objectId, AdaptiveInternalID internalId)
public AdaptiveFallbackElement ParseFallback(JToken fallbackJSON, JsonSerializer serializer, string objectId, AdaptiveInternalID internalId)
{
// Handle fallback as a string ("drop")
if (fallbackJSON.Type == JTokenType.String)
Expand Down
Loading