iconic / SVGInjector

Fast, caching, dynamic inline SVG DOM injection library
MIT License
975 stars 145 forks source link

Add ability to rewrite clipPath url() relative fragment id links in the SVG so they work properly when the <base> tag is being used #16

Open protodave opened 10 years ago

protodave commented 10 years ago

When using SVG clipPath elements, which are referenced and used via the url(#clip-path-id) syntax, adding the <base> tag to the page changes the meaning/location of that relative identifier fragment so the clipPaths can't be found (causing the SVG to not render as expected).

Using the <base> tag can also cause issues with SVG gradients, masks, markers, etc… which are also referenced by relative fragment id.

References: https://useiconic.com/community#!/tools:icons-not-displaying-correc http://stackoverflow.com/questions/24673855/svg-clip-path-working-locally-but-not-online

jeromepl commented 10 years ago

The solution I proposed in my post on the community (I am Jérôme P.) doesn't work when using a url containing a reference to an id on the page (ex: mysite.com#about) since window.location.href includes the part after the '#'. A possible solution to this would be to remove everything after the '#' by doing something like: window.location.href.replace(/#.*/, "");

ryanzec commented 10 years ago

This is a pretty big issue with Angular 1.3 as 1.3 now requires the base tag with HTML5 mode enabled (and I assume most people enabled this).

stryju commented 9 years ago

one could detect if <base> is present and if so, change all the url(#...) attributes with something like

var absoluteAttr = relativeAttr.replace(/(url\(\s*)#/, '$1' + window.location + '#')
fdanielsen commented 9 years ago

This is also an issue when using Ember with ember-cli, which also requires a <base> tag. The injector already rewrites the clip-path URL references (with sequential IDs) as far as I can tell, so it seems it should be possible for it to also prepend the full path to the SVG as it was loaded from.

JackCA commented 9 years ago

@fdanielsen I'm trying to do this in an ember-cli app as well. Did you by chance find a solution?

fdanielsen commented 9 years ago

Sorry, @JackCA, my solution in ember-cli was simply to remove the usage of the <base> tag. It didn't effect our Ember usage and was safe to remove for us.

protodave commented 9 years ago

Here's some additional reference for this issue, including mention of the new feature to opt-out of using the base tag with Angular:

https://github.com/angular/angular.js/issues/8934 1.3 : Requiring tags means I can't use SVG with clip-path, mask, etc...

rubenschulz commented 9 years ago

I have found a solution that works in my sites (I found this somewhere else). It is based on the solution from anecdot, replacing the the window location.

This does also work on pages with a reference to an ID (#) :-)

iconic.js - line 1030:

referencingElements[j].setAttribute(property, "url("+ window.location.href.replace(/#.*/, "") + "#" + newId + ")")

stryju commented 9 years ago

@rubenschulz https://github.com/iconic/SVGInjector/issues/16#issuecomment-62011707