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

Added support for the SvgScript tag #558

Merged
merged 8 commits into from
Aug 18, 2019
58 changes: 58 additions & 0 deletions Source/Document Structure/SvgScript.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml;

namespace Svg
{
/// <summary>
/// An element used to define scripts within SVG documents.
/// Use the Script property to get the script content (proxies the content)
/// </summary>
[SvgElement("script")]
public class SvgScript : SvgElement
{

public string Script
{
get { return this.Content; }
set { this.Content = value; }
}


[SvgAttribute("type")]
public string ScriptType
{
get { return GetAttribute<string>("type", false); }
set { Attributes["type"] = value; }
}


[SvgAttribute("crossorigin")]
public string CrossOrigin
{
get { return GetAttribute<string>("crossorigin",false); }
set { Attributes["crossorigin"] = value; }
}

[SvgAttribute("href")]
public string Href
{
get { return GetAttribute<string>("href", false); }
set { Attributes["href"] = value; }
}

public override SvgElement DeepCopy()
{
return DeepCopy<SvgScript>();
}

protected override void WriteChildren(XmlTextWriter writer)
{
if(!string.IsNullOrEmpty(Content))
{
//Always put the script in a CDATA tag
writer.WriteCData(this.Content);
}
}
}
}
4 changes: 2 additions & 2 deletions Source/Svg.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,11 @@
</ItemGroup>

<!-- Mac specific include -->
<!--

<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.2'">
<PackageReference Include="runtime.osx.10.10-x64.CoreCompat.System.Drawing" Version="5.8.64" />
</ItemGroup>
-->


<ItemGroup>
<Compile Remove=".\External\ExCSS\Parser.generated.cs" />
Expand Down
22 changes: 22 additions & 0 deletions Tests/Svg.UnitTests/Resources/ScriptTag/TestFile.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion Tests/Svg.UnitTests/Svg.UnitTests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IsTestProject>true</IsTestProject>
<TargetFrameworks>netcoreapp2.2;net452</TargetFrameworks>
<TargetFrameworks>netcoreapp2.2;</TargetFrameworks>
<!-- <TargetFrameworks>netcoreapp2.2;net452</TargetFrameworks> -->
<IsPackable>false</IsPackable>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>svgkey.snk</AssemblyOriginatorKeyFile>
Expand Down Expand Up @@ -67,6 +68,9 @@
<ItemGroup>
<EmbeddedResource Include="Resources\Issue518_Entities\Entities.svg" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\ScriptTag\TestFile.svg" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.1" />
<PackageReference Include="NUnit" Version="3.12.0" />
Expand Down
96 changes: 96 additions & 0 deletions Tests/Svg.UnitTests/SvgJavascriptTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using NUnit.Framework;
using System.IO;
using System.Linq;
using System.Xml;
using System.Collections.Generic;

namespace Svg.UnitTests
{
/// <summary>
/// Testing the capabilities to handle SVG documents with Javascript and the option to add
/// scripts to the SVG document.
/// </summary>
[TestFixture]
public class SvgJavascriptTests : SvgTestHelper
{
protected override string TestResource { get { return GetFullResourceString("ScriptTag.TestFile.svg"); } }

/// <summary>
/// Helper to retrieve the script element from the test document (expected in the root as type SvgScript with the elementname script)
/// Will assert the element not being null and of the correct type
/// </summary>
private SvgScript GetScriptElementFromDocument(SvgDocument doc)
{
var el = doc.Children.FirstOrDefault(c => c.ElementName == "script");
Assert.IsNotNull(el, "Could not find the script element");
Assert.IsAssignableFrom(typeof(SvgScript), el, "Script tag was not correctly typed, expected SvgScript as type");
return el as SvgScript;
}

/// <summary>
/// Check if a file with a script tag can correctly be read (and the types are as expected)
/// </summary>
[Test]
public void SvgDocumentWithSvgScript_ReadFile_ScriptTagReadFromSvgInCorrectType()
{
var doc = SvgDocument.Open(GetXMLDocFromResource(TestResource));
Assert.IsNotNull(doc);

var circleElement = doc.Children.FirstOrDefault(c => c.ElementName == "circle");
Assert.IsNotNull(circleElement, "Expected to find the circle element in the document");
Assert.IsAssignableFrom(typeof(SvgCircle), circleElement, "Expected the found circle element to be of type SvgCircle");

//Check if the type is correctly parsed
var scriptElement = GetScriptElementFromDocument(doc);
Assert.IsNotNull(scriptElement, "Expected to find the script element in the document");
}

/// <summary>
/// Test whether the attributes are parsed correctly (for now we only test the scripttype)
/// </summary>
[Test]
public void SvgDocumentWithSvgScript_AttributeParsing_CorrectTypeAttribute()
{
var doc = SvgDocument.Open(GetXMLDocFromResource(TestResource));
Assert.IsNotNull(doc);

var tag = GetScriptElementFromDocument(doc);
Assert.AreEqual("text/javascript", tag.ScriptType, "Expected the type attribute to be read");
}

/// <summary>
/// Retrieve the script content, this is not expected to be escaped. CDATA is handled by the SVG parser and should result in a "clean" script.
/// </summary>
[Test]
public void SvgDocumentWithSvgScript_RetrieveScriptContent_ScriptContentIsNotEscaped()
{
var doc = SvgDocument.Open(GetXMLDocFromResource(TestResource));
Assert.IsNotNull(doc);

var tag = GetScriptElementFromDocument(doc);
Assert.IsTrue(tag.Script.IndexOf("[DATA") < 0, "CDATA should not be in the content of the script");
}

/// <summary>
/// Try to add a script to a document and check if the content was added correctly
/// and escaped as expected.
/// </summary>
[Test]
public void SvgDocumentWithSvgScript_AddScript_EscapeAndTypeAdded()
{
//Script is expected to be escaped
var doc = new SvgDocument();
var script = new SvgScript();
script.Script = "alert('test');";
script.ScriptType = "text/javascript";
doc.Children.Add(script);
var docStr = doc.GetXML();

//Check if we found the type string and CDATA tags
Assert.IsFalse(string.IsNullOrWhiteSpace(docStr), "Expected document to be returned");
Assert.IsTrue(docStr.IndexOf("<script type=\"text/javascript\">") > -1, "Expected to find the script with type tag");
Assert.IsTrue(docStr.IndexOf("<![CDATA[") > -1, "Expected to find the CDATA start");
Assert.IsTrue(docStr.IndexOf("]]>") > -1, "Expected to find the CDATA ending");
}
}
}