SVG icon indicating copy to clipboard operation
SVG copied to clipboard

Adding support for <link> css inclusion

Open FabioFerrettiMoodys opened this issue 5 years ago • 15 comments

adding support for <Link ref="stylesheet" url="">

Adding support for css inclusion

Read the content of a <link rel="stylesheet" href="..> and add it like a

in order to do that, the base uri must be provided as the SvgDocument.BaseUri is set after the Open function.

FabioFerrettiMoodys avatar Apr 29 '20 06:04 FabioFerrettiMoodys

here is why the test are important ;)

i got a error in Open of svgDocument : i forgot the else ;)

   public static T Open<T>(string path, Dictionary<string, string> entities, Uri baseUri = null) where T : SvgDocument, new()
    {
        if (string.IsNullOrEmpty(path))
        {
            throw new ArgumentNullException("path");
        }

        if (!File.Exists(path))
        {
            throw new FileNotFoundException("The specified document cannot be found.", path);
        }

        using (var stream = File.OpenRead(path))
        {
            var doc = Open<T>(stream, entities, baseUri == null ? new Uri(System.IO.Path.GetFullPath(path)) : baseUri);
            if (baseUri == null)
                doc.BaseUri = new Uri(System.IO.Path.GetFullPath(path));
            else
                doc.BaseUri = baseUri;
            return doc;
        }
    }

FabioFerrettiMoodys avatar Apr 29 '20 09:04 FabioFerrettiMoodys

@H1Gdev - are there open review issues here?

mrbean-bremen avatar Jun 07 '20 17:06 mrbean-bremen

There is no <link> element in the SVG specifications.

@FabioFerrettiMoodys

Please add target SVG files to your test. Please tell me supported software (major browser etc.).

H1Gdev avatar Jun 08 '20 10:06 H1Gdev

Hello

https://www.w3.org/TR/SVG2/styling.html

6.3. External style sheets: the effect of the HTML ‘link’ element
An HTML ‘link’ element in an SVG document (that is, an element in the HTML namespace with local name "link") with its ‘rel’ attribute set to 'stylesheet' must be processed as defined in the HTML specification and cause external style sheets to be loaded and applied to the document. Such elements in HTML documents outside of an inline SVG fragment must also apply to the SVG content.

all major browser seems to support it i've test this sample with chrome, ie11 and firefox. http://www.schepers.cc/svg/style/external-link-xhtml.svg

FabioFerrettiMoodys avatar Jun 08 '20 11:06 FabioFerrettiMoodys

This PR has the following issues.

  • File output by Write is not supported.
  • Do not support the case if href is specified in URL.

First, make the following changes.

  • Create an element for <link>.
  • BaseUri is a user-settable property, so please resolve link href later.

H1Gdev avatar Jun 09 '20 04:06 H1Gdev

FYI

Output SVG with this PR is as follows.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0, 0, 50, 50" xhtml="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xml="http://www.w3.org/XML/1998/namespace" version="1.1">
  <title>Styling Test</title>
  <desc>
    Tests linking to external stylesheet with "link" element in XHML namespace.  
    Seems to work in Firefox, Opera, and Safari, as of 18-01-2009
  </desc>
  <metadata>author: schepers, created: 18-01-2009</metadata>
  <link href="svgstyle.css" rel="stylesheet" type="text/css">circle
{
   fill: lime;
   stroke: green;
   stroke-width: 10px;
}
</link>
  <circle cx="25" cy="25" r="20" stroke-width="10px" style="fill:lime;stroke:green;" />
</svg>

H1Gdev avatar Jun 09 '20 04:06 H1Gdev

  • BaseUri is a user-settable property, so please resolve link href later.

i don't know how to do it, you collect all the styles in the function Open<T>(XmlReader reader... You create a "resulting css" named "cssTotal" and assign the styles to te elements at the end of these function : before we can set the BaseUri. line 480 of svgDocument.cs var cssTotal = styles.Select((s) => s.Content).Aggregate((p, c) => p + Environment.NewLine + c);

FabioFerrettiMoodys avatar Jun 10 '20 09:06 FabioFerrettiMoodys

@mrbean-bremen @FabioFerrettiMoodys

By #90, BaseUri property can be set... We plan to ensure backward compatibility as much as possible.

This is modification to review style application sequence by supporting the SVG2 specification.

H1Gdev avatar Jun 10 '20 11:06 H1Gdev

@H1Gdev

By #90, BaseUri property can be set... We plan to ensure backward compatibility as much as possible.

This is modification to review style application sequence by supporting the SVG2 specification.

I'm not sure to follow you : it can be set but only after the Open. but the styling is done in the Open. (SvgDocument.cs line 507 : svgDocument?.FlushStyles(true); ). i can make a link element and resolve the href later, but if a user set it, it will not work as all the styling is done at the open of the file. (if it's a new element, i will also need to redo the aggregate of styles at the end of the Open function. As the aggregate of the ISvGNode.Content will not work anymore.)

ps: sorry but i'm struggling to understand your comments and what and how you want me to do. I don't know your library as deep as you. Can you be more specific ?

for exemple what do you mean by "File output by Draw is not supported."

var svg = SvgDocument.Open(Source);
var image = svg.Draw();

this code work, do you mean something else ?

I also don't understand your "Output SVG with this PR is as follows." how do you generate it like this ? i didn't alter the svgdocument structure, i've only added the css content to the list of styles used for the styling at the end of the Open.

FabioFerrettiMoodys avatar Jun 12 '20 08:06 FabioFerrettiMoodys

for exemple what do you mean by "File output by Draw is not supported."

It's a typo.

  • File output by Write is not supported.

H1Gdev avatar Jun 12 '20 10:06 H1Gdev

it can be set but only after the Open. but the styling is done in the Open. (SvgDocument.cs line 507 : svgDocument?.FlushStyles(true); ).

This is because it doesn't support <link>. This is because we was able to solve style here.

Now, the changes that are considered are the following.

  1. Make setting of BaseUri property private so that it can be set only in Open method.
  2. Apply style before Draw.

The change of 1 cannot maintain backward compatibility.

Maybe, I think change of 2 will be like SvgDeferredPaintServer.

H1Gdev avatar Jun 13 '20 00:06 H1Gdev

As the link element wasn't in the svg namespace i've added a NonSvgElementAttribute so the SvgElementFactory can create NonSvgElement by refraction like the SvgElement.

i've assigned the BaseUri just after the creation of the svgdocument in the open function : the svglink use the OwnerDocument.BaseUri when the content of the link is requested. (svgLink.GetLinkContentAsText)

i've corrected the svgDocument.Write : it write the element, but i don't know if it is what you want as the styles are already added on each elements (by the flushstyles function).

FabioFerrettiMoodys avatar Jun 15 '20 08:06 FabioFerrettiMoodys

@H1Gdev - can you please check if the current state can be merged? You did some review that has been addressed (admittetly, this was quite some time ago, but I hadn't been active in this project since then).

mrbean-bremen avatar Dec 27 '20 14:12 mrbean-bremen

(If #872 is merged and this pull request is resumed, it should check that SvgDocument.ResolveExternalResources == true before creating a WebRequest in GetLinkContentAsStream.)

kimsey0 avatar May 14 '21 12:05 kimsey0

@FabioFerrettiMoodys Sorry for the delay. Please update your project for review.

paulushub avatar Jan 14 '24 14:01 paulushub