Make WordPress Core

Opened 9 years ago

Closed 8 years ago

Last modified 8 years ago

#35824 closed defect (bug) (fixed)

Inline svg icons are not displaying when the page is viewed from Customizer's iframe

Reported by: johndoedoe's profile johndoedoe Owned by:
Milestone: 4.7 Priority: normal
Severity: normal Version: 4.4.2
Component: Customize Keywords:
Focuses: Cc:

Description (last modified by westonruter)

For example if we have inline definition

<svg width="0" height="0" style="position:absolute">
<symbol viewBox="0 0 14 14" id="icon-money"><path d="M12.3 5.5c.1-.3.2-.6.2-1 0-2-2.4-3.5-5.5-3.5S1.5 2.6 1.5 4.5c0 .4.1.7.2 1-.1.3-.2.7-.2 1 0 .4.1.7.2 1-.1.3-.2.7-.2 1 0 2 2.4 3.5 5.5 3.5s5.5-1.5 5.5-3.5c0-.3-.1-.7-.2-1 .1-.3.2-.6.2-1 0-.3-.1-.6-.2-1zM7 8c1.9 0 3.5-.6 4.5-1.5C11.5 7.9 9.4 9 7 9S2.5 7.9 2.5 6.6C3.5 7.5 5.1 8 7 8zm0-6c2.4 0 4.5 1.1 4.5 2.5S9.4 7 7 7 2.5 5.9 2.5 4.5 4.6 2 7 2zm0 9c-2.4 0-4.5-1.1-4.5-2.5 1 1 2.6 1.5 4.5 1.5s3.5-.6 4.5-1.5C11.5 9.9 9.4 11 7 11z"/></symbol>
</svg>

and then use it like this

<svg>
    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-money"></use>
</svg>

when viewed directly - works fine, but from customizer it is not displayed.
However, the externally linked svg icons

<svg>
    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/img/some-sprite.svg#icon-money"></use>
</svg>

do work fine.

Tested in chrome and firefox.

Attachments (1)

svg-inline-and-injected-iframe-test.zip (2.6 KB) - added by bentleykfrog 9 years ago.
Inline SVG's fail to render in iframes with js injected content when the iframe document's base tag doesn't match the history state in chrome 48

Download all attachments as: .zip

Change History (12)

#1 @westonruter
9 years ago

  • Description modified (diff)
  • Milestone changed from Awaiting Review to Future Release

I cannot reproduce the issue in Chrome 48, however I can reproduce it in Firefox 43.

I have a feeling that the issue here is similar to #23225 and will be resolved with the implementation of #30028.

#2 @aut0poietic
9 years ago

I can't reproduce the original issue as described (screen shot shows multiple, single-color SVG's working fine in customizer), but I can confirm similar behavior ( SVG's vanish in customizer ) in Chrome 48.0.2564.103 (64-bit), Firefox 44.0.2, & Safari 9.0.3 - all Mac OS 10.11.3.

I've narrowed it down to the SVG Gradients and SVG Filters. Remove the gradient and the filter then the SVG appears.

Steps to reproduce:

1) Insert this svg into your active theme file ( mine are in the header.php, positioned absolutely ): https://gist.github.com/aut0poietic/f95e3c53bfba77b58984
2) Confirm visible in main site.
3) View theme in customizer.

This behavior occurs if the SVG is used as an placed directly in the page or if added as a symbol displayed with a use xmlns:xlink.

Screen shots:

Visible in Site:
https://dl.dropboxusercontent.com/u/1061487/svg-customizer-bug-site.jpg
Gone in Customizer:
https://dl.dropboxusercontent.com/u/1061487/svg-customizer-bug-c-open.jpg

Note that the "stars" in the background are also SVG's, inserted with <use> but I removed their gradients & shadows.

Can't do more than speculate, but I'm guessing that something is either altering the ID's of the gradients in the filter attributes of the destination svg or the id attribute of the source gradient/filter.

#3 @westonruter
9 years ago

  • Milestone changed from Future Release to 4.6

@bentleykfrog
9 years ago

Inline SVG's fail to render in iframes with js injected content when the iframe document's base tag doesn't match the history state in chrome 48

#4 @bentleykfrog
9 years ago

I am able to reproduce this in Chrome 49.0.2623.112.

From investigation it appears to be a combination of a base href tag in the iframe's document and the fact that the iframe is injected without a history state. If there is a history state that matches the base href's value or the base href is removed, inline svgs work. See the svg-inline-and-injected-iframe.zip file I attached for a testable example of this. Remove the <base> tag or uncomment the .replaceState line in the js.

You could change the api.PreviewFrame's iframe injection from this

	self.targetWindow( self.iframe[0].contentWindow );

	self.targetWindow().document.open();
	self.targetWindow().document.write( response );
	self.targetWindow().document.close();

to this

	self.targetWindow( self.iframe[0].contentWindow );
	
	self.targetWindow().document.open();
	//origin matches the base href value in the iframe
	self.targetWindow().history.pushState( {}, '', self.origin() );
	self.targetWindow().document.write( response );
	self.targetWindow().document.close();

to fix the issue without removing the <base> tag.

@aut0poietic i'm concerned that your issue might be caused by this https://github.com/w0rm/gulp-svgstore/issues/31
is your svg sprite hidden by display:none? try:

width: 0; height: 0; visibility: hidden; position: absolute;

#5 @aut0poietic
9 years ago

@bentleykfrog Thanks for the suggestion. Unfortunately, my symbol-defs svg file uses similar technique to yours but without the visibility:hidden.

I'm seeing the behavior regardless of whether I'm adding the SVG as a symbol and using xlink or inserting the direct SVG markup in the page. The example SVG I provided above (https://gist.github.com/aut0poietic/f95e3c53bfba77b58984) can be directly inserted into a theme as markup (not as a symbol) and the behavior persists: Normal site viewing the SVG works perfectly, but the SVG completely dissappears (not just the gradient and filters) in customizer view.


#6 @Kelderic
9 years ago

This might be related to a Chrome bug that causes Chrome not to find any filters that are linked via url(#id) when the url is linking to an external page.

https://bugs.chromium.org/p/chromium/issues/detail?id=109212

I discovered a work around that the SVG containing the defs/symbols needs to be in the same URL structure as the display SVG. Not sure if that will help here.

#7 follow-up: @bentleykfrog
9 years ago

@aut0poietic Thanks for confirming that. I was able to reproduce your issue in Safari 9.1. In Firefox 46.0b9 & Chrome 50.0.2661.86 the issue is more like the O.P.

In Safari 9.1 on Mac:
Only shapes that are filled with gradients using fragment identifiers & filters using similar fragment identifiers are not displaying. SVG shapes with solid fills do display. Adding a history state that matches the base href on iframe document.write() fixed this in safari after flushing its cache and refreshing the page.

Chrome 50.0.2661.86 on Mac and Windows & Firefox 46.0b9 on Mac show the same issues as the O.P. All SVG elements that use fragment identifiers to reference inline content don't display the referenced content. Again adding a history state that matches the base href on iframe document.write() fixes this issue.

#8 in reply to: ↑ 7 @bentleykfrog
9 years ago

Sorry for the late comment, just had a chance to check out #30028 which has resolved the issue.

#9 @celloexpressions
9 years ago

  • Milestone changed from 4.6 to Future Release

Punting as #30028 has been punted to future and this is fixed by that ticket.

#10 follow-up: @westonruter
8 years ago

  • Milestone changed from Future Release to 4.7
  • Resolution set to fixed
  • Status changed from new to closed

@johndoedoe This should be resolved now that #30028 is closed and the customizer preview window is loaded naturally instead of using document.write(). Please re-open if this is not the case.

#11 in reply to: ↑ 10 @johndoedoe
8 years ago

Replying to westonruter:

@johndoedoe This should be resolved now that #30028 is closed and the customizer preview window is loaded naturally instead of using document.write(). Please re-open if this is not the case.

Thank you. Opened #39143

Note: See TracTickets for help on using tickets.