SVG clip-path not working - multiple svgs on same page [duplicate] - svg

This question already has an answer here:
clipPath in multiple SVG tags
(1 answer)
Closed 5 years ago.
I have multiple svgs on one page and have exported them individually from illustrator. I also passed them through omgsvg which reduced the file size.
However, when I view the complete page with all of my separate svgs inserted (via my server side html rendering engine), many of the clip paths don't seem to be functioning. Some do and some don't, I can't work out why.
Svgomg helped but didn't solve the problem entirely. Some paths still don't function.
But all the clip paths work fine when loaded one at a time as individual svgs directly in chrome, or in the illustration program! They only fail when put together in the html page.

The cause of this problem is that during svg export, clip paths will be defined using standardised ids, chosen by your illustration program. If you export several files, each of these files may well use the same id names. Svgomg just uses letters, a,b... Illustrator uses SVGID_1_, ...
What you need to remember is the role of ids on an html page.
Ids must be unique. Clip paths are failing to work because you have the same id defined more than once when you insert multiple individually exported files. The solution is to think of your html page as a whole, and make sure your ids across all images you will have on a page will be unique.

Related

Why does TYPO3 remove values of style="" attributes during SVG rendering?

On my TYPO3 v10 website I have some SVG icons in use, no problem.
I also have a few more complex SVG Figures (created with Inkscape), that I want to include in TYPO3 website. Of course I can upload the .svg files to the fileadmin/ folder, and link to them with the Text+Image (or Text+Media) Content Elements.
In the Backend, TYPO3 generates some fine png-thumbnails for preview. So far so good.
The file can be downloaded directly, from its fileadmin/images ... location.
However, inside web pages, my SVGs are not displayed as they should.
A lot of styling information gets removed from the SVG and I don't know where.
Here is a screenshot of the original vs corrupted image (as displayed in the TYPO3 frontend).
Here is a graphical diff that shows the difference between the figures.
It turns out that at some time during the rendering process, TYPO3 removes the values from the style="...." SVG attributes. See reddish boxes.
All my more complex SVGs look like the one on the right when embedded in TYPO3.
Here is the SVG if you want to try yourself: image on SVGshare.com
On the right, many style attributes have been set to style="".
but why?
It's Firefox, not TYPO3, who removes the style="..." attribute values. This seems to be a longstanding Firefox Issue, solved.
See Bugzilla Issue 1262842: [CSP] Blocks the use of style attributes inside SVG without generating console errors.
Look for "triply confusing" in the first comment.
Inline CSS styles can be a security Problem, and therefore Firefox has a Content-Security-Policy (CSP) in place, in order to correct this.
An explainer for the mitigation strategies, written jointly by professional Security Engineers is given in this Google Doc and in Gihub Repo (Content Security Policy), Issue 45, Further granularity of unsafe-inline styles.
Script inline attributes are a difficult subject to approach when it
comes to CSP, they have the same amount of power as any other script
element but they don’t have ways to be whitelisted, for example, by a
nonce or hash. This means that the actual content of the attribute is
mostly the only deciding factor.
I don't understand everything mentioned in these docs and discussions. Inline-style Elements seem to be vulnerable to XSS attacks, and then attacker can put CSS url() in there for instance.
Quick-and-dirty solution
Use Inkscape and save as "optimized SVG", and check the option "Convert CSS Attributes to XML attributes". See attached screenshot of the Inkscape Dialog (Linux).
This solution was proposed by a web-developer from the GIMP devteam.
TYPO3 9 introduced an SVG Sanitizer, which automatically modifies SVG files during "fileadmin upload time", meaning it removes any <style ...> elements from the uploaded SVG file.
In TYPO3 10 and later versions, this SVG Sanitizer is by default automatically set up via Symfony dependency injection via core's Services.yaml.
You can remove the SVG Sanitizer via your own site extension's Services.yaml, e.g. for your myextension/Configuration/Services.yaml:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
# ...
# remove TYPO3's default-autowired SvgSanitizer, which tampers with filadmin uploaded SVGs (e.g. removes necessary <style> information)'
TYPO3\CMS\Core\Resource\Security\SvgEventListener: ~
The tilde (~) removes/overwrites the definition previously set up by core's Services.yaml ( https://symfony.com/doc/current/service_container/service_decoration.html ).
This seems to be a problem of your individual TYPO3 installation. I've just tested your SVG image in a brand new TYPO3 v10 installation and the image is rendered properly in backend and frontend.
Maybe you have some 3rd party extensions installed who postprocess the HTML output of TYPO3, e.g EXT:sourceopt or EXT:scriptmerger.

Handling SVG elements using Karate UI Automation [duplicate]

This question already has an answer here:
Karate UI button click support
(1 answer)
Closed 2 years ago.
I am quite new to Karate UI automation and I have a front end UI that has a SVG element which when clicked brings a drop down.
When I am writing the UI test for it, I get javascript evaluation error and hence seek some advice/help.
Here are the screenshots of the UI element and its CSS locator clearly seen on the screen
This is how the CSS locator shows up for the SVG element
This uniquely identifies the SVG element(the plus button)
svg[class='svg-inline--fa fa-plus-square fa-w-14 ']
This is the part of code that I have written to click it
And click("svg[class='svg-inline--fa fa-plus-square fa-w-14 ']")
And here is the error I get:
javascript evaluation failed: click("svg[class='svg-inline--fa fa-plus-square fa-w-14 ']"), js eval failed twice:document.querySelector("svg[class='svg-inline--fa fa-plus-square fa-w-14 ']").click(), error: {"type":"object","subtype":"error","className":"TypeError","description":"TypeError: Cannot read property 'click' of null\n at <anonymous>:1:78","objectId":"{\"injectedScriptId\":2,\"id\":3}"}
I tried various things that can uniquely identify the SVG element like using the compelete Xpath and also using the parent class name(though it was already unique with just the class name) but it still did not work. I tried wildcard locators as well but since there is no text/name of the element, it did not work. When the tags are say input or button etc the same way of css locator works but SVG ones did not for me.
tagname[unique_id of the element like key=value pair]
I am wondering if we need to use a different way to identify SVG elements using Karate UI? The same path when used in Selenium worked.
Since this is a UI that requires VPN connection and secure acccess, it may not be possible to provide a minimum code to try and replicate it. But am happy to provide more details if needed.
I have many such SVG elements on my UI and any help in this would be greatly appreciated.
Use selector hub as an extension to chrome, firefox, edge and opera. Ive only used with chrome and it worked fine and allowed me to quickly and easily find svg relative / absolute xpath. This worked no problems in a find and click capacity on numerous svg elements (via karate script)
2 suggestions.
Try to get some nearby element and work backwards: https://stackoverflow.com/a/63988977/143475
Figure out the location of the SVG and fire a mouse-click: https://stackoverflow.com/a/63828083/143475
Unable to give you specifics without a way to replicate, but - it should be possible to find a "pattern" so you can write a custom function as described in the docs. So that can be your goal, something like this:
* svgClick('svg-inline--fa')

Mobile Safari fails to scroll to named anchor

I have a big SVG document here, containing a map of all the quests in a certain online game. Each quest node is inside a SVG <a> element, linking to a distinct named anchor in a big HTML document that loads in another tab, containing further details about that particular quest. This works exactly as desired in desktop Safari, and I'd expect it to work just as well in any browser that supports SVG at all since I'm using only the most basic form of linking, but it fails badly on Mobile Safari (iOS 6) - which is my single most important browser target, considering that the game in question is for the iPad. It only scrolls to the correct anchor on the initial load of the HTML page; clicking a different quest in the SVG tab will cause a switch to the HTML tab, and the hash (fragment ID) in the address bar changes, but the page doesn't auto-scroll.
This appears to be a known limitation in Mobile Safari - hash-only changes in the URL apparently used to force a page reload, and that got over-fixed such that nothing gets triggered at all now. The fixes I've found online all seem to be applicable only in cases where the URL change is being generated programatically, from within the same document, rather than static links from a different document.
Further details:
I've tried doing the named anchors in both the old <a name="..."> form, and the newer <h1 id="..."> form. No difference.
I've tried adding an onhashchange handler, to force the scrolling to take place, but the handler isn't being called at all (verified by putting an alert() in it).
I could presumably fix the problem by having each quest's details in a separate HTML file, but that would severely affect usability - with all the details in a single file, you can use your browser's Find feature to search through them all at once. (Also, deploying 1006 files to my web hosting after each update would be a bit of a pain...)
Anybody have an idea for a work-around?

Create a map with clickable provinces/states using SVG, HTML/CSS, ImageMap

I am trying to create an interactive map where users can click on different provinces in the map to get info specific to that province.
Example:
archived: http://www.todospelaeducacao.org.br/
archived: http://code.google.com/p/svg2imap/
So far I've only found solutions that have limited functionality. I've only really searched for this using an SVG file, but I would be open to other file types if it is possible.
If anyone knows of a fully functioning way to do this (jQuery plug-in, PHP script, vector images) or a tutorial on how to do it manually please do share.
jQuery plugin for decorating image maps (highlights, select areas, tooltips):
http://www.outsharked.com/imagemapster/
Disclosure: I wrote it.
Sounds like you want a simple imagemap, I'd recommend to not make it more complex than it needs to be. Here's an article on how to improve imagemaps with svg. It's very easy to do clickable regions in svg itself, just add some <a> elements around the shapes you want to have clickable.
A couple of options if you need something more advanced:
http://jqvmap.com/
http://jvectormap.com/
http://polymaps.org/
I think it's better to divide my answer to 2 parts:
A-Create everything from scratch (using SVG, JavaScript, and HTML5):
Create a new HTML5 page
Create a new SVG file, each clickable area (province) should be a separate SVG Polygon in your SVG file,
(I'm using Adobe Illustrator for creating SVG files but you can find many alternative software products too, for example Inkscape)
Add mouseover and click events to your polygons one by one
<polygon points="200,10 250,190 160,210" style="fill:lime;stroke:purple;stroke-width:1"
onmouseover="mouseOverHandler(evt)"
onclick="clickHandler(evt)" />
Add a handler for each event in your JavaScript code and add your desired code to the handler
function mouseOverHandler(evt) {};
function clickHandler(evt) {};
Add the SVG file to your HTML page (I prefer inline SVG but you can use linked SVG file too)
Upload the files to your server
B-Use a software like FLDraw Interactive Image Creator (only if you have a map image and want to make it interactive):
Create an empty project and choose your map image as your base image when creating the new project
Add a Polygon element (from the Shape menu) for each province
For each polygon double click it to open the Properties window where you can choose an event type for mouse-over and click,
also change the shape opacity to 0 to make it invisible
Save your project and Publish it to HTML5, FLDraw will create a new folder that contains all of the required files for your project that you can upload to your server.
Option (A) is very good if you are programmer or you have someone to create the required code and SVG file for you,
Option (B) is good if you don't want to hire someone or spend your own time for creating everything from scratch
You have some other options too, for example using HTML5 Canvas instead of SVG, but it's not very easy to create a Zoomable map using HTML5 Canvas,
maybe there are some other ways too that I'm not aware of.
Just in case anyone will search for it - I used it on several sites, always the customization and RD possibilities were a perfect fit for what I needed. Simple and it is free to use:
Clickable CSS Maps
One note for more scripts on a site: I had some annoying problems with getting to work a map (that worked as a graphic menu) in Drupal 7. There where many other script used, and after handling them, I got stuck with the map - it still didn't work, although the jquery.cssmap.js, CSS (both local) and the script in the where in the right place. Firebug showed me an error and I suddenly eureka - a simple oversight, I left the script code as it was in the example and there was a conflict. Just change the front function "$" to "jQuery" (or other handler) and it works perfect. :]
Here's what I ment (of course you can put it before instead of the ):
<script type="text/javascript">
jQuery(function($){
$('#map-country').cssMap({'size' : 810});
});
</script>
Go to SVG to Script
with your SVG the default output is the map in SVG
Code which adds events is also added but is easily identified and can be altered as required.
I have been using makeaclickablemap for my province maps for some time now and it turned out to be a really good fit.
I had the same requirements and finally this Map converter worked for me. It is the best plugin for any map generation.
Here is another image map plugin I wrote to enhance image maps: https://github.com/gestixi/pictarea
It makes it easy to highlight all the area and let you specify different styles depending on the state of the zone: normal, hover, active, disable.
You can also specify how many zones can be selected at the same time.
The following code may help you:
$("#svgEuropa [id='stallwanger.it.dev_shape_DEU']").on("click",function(){
alert($(this).attr("id"));
});
Source
You have quite a few options for this:
1 - If you can find an SVG file for the map you want, you can use something like RaphaelJS or SnapSVG to add click listeners for your states/regions, this solution is the most customizable...
2 - You can use dedicated tools such as clickablemapbuilder (free) or makeaclickablemap (i think free also).
[disclaimer] Im the author of clickablemapbuilder.com :)
<script type="text/javascript">
jQuery(function($){
$('#map-country').cssMap({'size' : 810});
});
</script>
strong text

SVG with external images doesn't load them when embedded with <img> tag in browsers

I made the following observation:
If I create an svg image that references an external raster image via xlink:href and try to load the svg in browsers, the external images are only shown if I use the <object> tag, but not when using the <img> tag.
Rendering with the <object> tag is quite slow and not as clean as using the img tag for images so I was wondering if there's a way to make it work through the <img> tag.
At first I thought it doesn't work because of a same origin policy, but even if the referenced image is in the same directory and I reference it through its name only, it wont load.
Any ideas?
Are you using IE? IE doesnt recognize SVG anyway. Microsoft is always ten years behind, yet they are more popular and far more costly, for some reason. Name brand propaganda?
SVG loads in Firefox. Both as an XML document referenced directly in the URL, and also if you embed it into an XHTML (fully XML compliant) document with proper namespacing, the SVG should render properly. The great thing about this option is that DHTML can manipulate your SVG. Everything I said in this paragraph also applies to MathML, if youre curious.
Aside from that, SVG doesn't load from an image tag. I do believe Firefox is working on this upgrade, though. Im not entirely sure.
Using the object or embed tag is reasonable, I suppose... but one of my earlier fixes was to use an iframe. Embed an iframe in your html that references the complete SVG file. Using CSS you can make the iframe look flush with the rest of your document, appearing and acting like an image. Encased in a div or span tag, you can have onhover and onclick event handlers.
Using the image tag, your src can be a PHP file on server side. If properly coded and with the appropriate cgi apps, you can rasterize your SVG on server-side, and have that PNG data sent back to your image via the PHP src.
There's no particular reason <object> should be any slower to load than <img> apart from possibly the interaction aspect (img's are static while object's are fully interactive documents). The images inside the svg should load in both scenarios, so it sounds like a bug in the browser.
Could you post a link to your example?
I think you are at least 10 months behind...IE9 supports SVG, and pre-release versions (including a beta) have been out for quite a while. Check out www.ietestdrive.com to grab the platform preview - it's pretty good. In my opinion, parts of their SVG support are much better than Firefox currently (but they don't support SMIL yet).

Resources