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

Feature Request: Allow svg images #1103

Open
TBK opened this issue Nov 1, 2018 · 5 comments
Open

Feature Request: Allow svg images #1103

TBK opened this issue Nov 1, 2018 · 5 comments

Comments

@TBK
Copy link
Contributor

TBK commented Nov 1, 2018

Describe the feature you'd like
Make it possible to upload svg images.

Describe the benefits this feature would bring to BookStack users
Scalable Vector Graphics FTW 👍

Additional context
This is what happens at the moment:
image

@wouterloedeman
Copy link

I agree. Would be nice if they could be used as application logo as well!

@xblitz
Copy link

xblitz commented Nov 8, 2018

Yes! Just tried using SVG logo since the current requirement of 43px Height looks bad on HiDPI Screens (4k, phones)

@bharatrajagopalan
Copy link

bharatrajagopalan commented Dec 16, 2018

Hi

EDIT: a slight tweak that lets me get rid of the div element by using the beforeInject hook of SVGInject

Not perfect but managed to get interactive SVG working with the following

I am using plantuml to generate SVG for UML diagrams

I upload svgs as attachments and then am using styles to add a nice grey background. i am using the excellent SVGinject javascript to find img tags with class plantsvg and replace it with the SVG content. Consequently as SVG is basically html text, i am using an enclosing div to center it

Paste this into Settings > Custom HTML Head

image

<style> 
 .plantsvg  {
   height:auto;
   background-color:#FAFAFA;
   padding:20px;
   max-width:100%;
 }

 .plantdiv {
   text-align:center;

 } 
</style>

<script>


!function(o,l){var r,a,s="createElement",y="getElementsByTagName",g="length",E="style",d="title",b="undefined",h="setAttribute",k="getAttribute",w=null,x="__svgInject",A="--inject-",C=new RegExp(A+"\\d+","g"),S="LOAD_FAIL",t="SVG_NOT_SUPPORTED",I="SVG_INVALID",v=["src","alt","onload","onerror"],L=l[s]("a"),j=typeof SVGRect!=b,f={useCache:!0,copyAttributes:!0,makeIdsUnique:!0},G={clipPath:["clip-path"],"color-profile":w,cursor:w,filter:w,linearGradient:["fill","stroke"],marker:["marker",
"marker-end","marker-mid","marker-start"],mask:w,pattern:["fill","stroke"],radialGradient:["fill","stroke"]},u=1,c=2,N=1;function O(e){return(r=r||new XMLSerializer).serializeToString(e)}function T(e){var t,r,n,i,o=A+N++,a=e.querySelectorAll("[id]"),f={},u=[],c=!1;for(n=0;n<a[g];n++)(r=(t=a[n]).localName)in G&&(c=!0,f[r]=1,t.id+=o,["xlink:href","href"].forEach(function(e){var r=t[k](e);/^\s*#/.test(r)&&t[h](e,r.trim()+o)}));for(r in f)(G[r]||[r]).forEach(function(e){u.indexOf(e)<0&&u.push(e)})
;if(u[g]){u.push(E);var l,s,d,v,p=/url\("?#([a-zA-Z][\w:.-]*)"?\)/g,m=e[y]("*");for(n=0;n<m[g];n++)if((l=m[n]).localName==E)(v=(d=l.textContent)&&d.replace(p,"url(#$1"+o+")"))!==d&&(l.textContent=v);else if(l.hasAttributes())for(i=0;i<u[g];i++)s=u[i],(v=(d=l[k](s))&&d.replace(p,"url(#$1"+o+")"))!==d&&l[h](s,v)}return c}function P(e,r,t,n){if(r){r[h]("data-inject-url",t);var i=e.parentNode;if(i){n.copyAttributes&&function c(e,r){for(var t,n,i,o=e.attributes,a=0;a<o[g];a++)if(n=(t=o[a]).name,
-1==v.indexOf(n))if(i=t.value,n==d){var f,u=r.firstElementChild;u&&u.localName.toLowerCase()==d?f=u:(f=l[s+"NS"]("http://www.w3.org/2000/svg",d),r.insertBefore(f,u)),f.textContent=i}else r[h](n,i)}(e,r);var o=n.beforeInject,a=o&&o(e,r)||r;i.replaceChild(a,e),e[x]=u,m(e);var f=n.afterInject;f&&f(e,a)}}else _(e,n)}function p(){for(var e={},r=arguments,t=0;t<r[g];t++){var n=r[t];for(var i in n)n.hasOwnProperty(i)&&(e[i]=n[i])}return e}function V(e,r){if(r){var t;try{t=function i(e){return(
a=a||new DOMParser).parseFromString(e,"text/xml")}(e)}catch(o){return w}return t[y]("parsererror")[g]?w:t.documentElement}var n=l.createElement("div");return n.innerHTML=e,n.firstElementChild}function m(e){e.removeAttribute("onload")}function n(e){console.error("SVGInject: "+e)}function i(e,r,t){e[x]=c,t.onFail?t.onFail(e,r):n(r)}function _(e,r){m(e),i(e,I,r)}function D(e,r){m(e),i(e,t,r)}function F(e,r){i(e,S,r)}function M(e){e.onload=w,e.onerror=w}function q(e){n("no img element")}
var e=function R(e,r){var t=p(f,r),h={};function n(a,f){f=p(t,f);var e=function(r){var e=function(){var e=f.onAllFinish;e&&e(),r&&r()};if(a&&typeof a[g]!=b){var t=0,n=a[g];if(0==n)e();else for(var i=function(){++t==n&&e()},o=0;o<n;o++)u(a[o],f,i)}else u(a,f,e)};return typeof Promise==b?e():new Promise(e)}function u(u,c,e){if(u){var r=u[x];if(r)Array.isArray(r)?r.push(e):e();else{if(M(u),!j)return D(u,c),void e();var t=c.beforeLoad,n=t&&t(u)||u[k]("src");if(!n)return""===n&&F(u,c),void e()
;var i=[];u[x]=i;var l=function(){e(),i.forEach(function(e){e()})},s=function f(e){return L.href=e,L.href}(n),d=c.useCache,v=c.makeIdsUnique,p=function(r){d&&(h[s].forEach(function(e){e(r)}),h[s]=r)};if(d){var o,a=function(e){if(e===S)F(u,c);else if(e===I)_(u,c);else{var r,t=e[0],n=e[1],i=e[2];v&&(t===w?(t=T(r=V(n,!1)),e[0]=t,e[2]=t&&O(r)):t&&(n=function o(e){return e.replace(C,A+N++)}(i))),r=r||V(n,!1),P(u,r,s,c)}l()};if(typeof(o=h[s])!=b)return void(o.isCallbackQueue?o.push(a):a(o));(o=[]
).isCallbackQueue=!0,h[s]=o}!function m(e,r,t){if(e){var n=new XMLHttpRequest;n.onreadystatechange=function(){if(4==n.readyState){var e=n.status;200==e?r(n.responseXML,n.responseText.trim()):400<=e?t():0==e&&t()}},n.open("GET",e,!0),n.send()}}(s,function(e,r){var t=e instanceof Document?e.documentElement:V(r,!0),n=c.afterLoad;if(n){var i=n(t,r)||t;if(i){var o="string"==typeof i;r=o?i:O(t),t=o?V(i,!0):i}}if(t instanceof SVGElement){var a=w;if(v&&(a=T(t)),d){var f=a&&O(t);p([a,r,f])}P(u,t,s,c)
}else _(u,c),p(I);l()},function(){F(u,c),p(S),l()})}}else q()}return j&&function i(e){var r=l[y]("head")[0];if(r){var t=l[s](E);t.type="text/css",t.appendChild(l.createTextNode(e)),r.appendChild(t)}}('img[onload^="'+e+'("]{visibility:hidden;}'),n.setOptions=function(e){t=p(t,e)},n.create=R,n.err=function(e,r){e?e[x]!=c&&(M(e),j?(m(e),F(e,t)):D(e,t),r&&(m(e),e.src=r)):q()},o[e]=n}("SVGInject");"object"==typeof module&&"object"==typeof module.exports&&(module.exports=e)}(window,document);

</script>

<script>
    SVGInject.setOptions({
     
      beforeInject: function(img, svg) {
        // svg text alignment set via div
        //ensure that svg aspect ratio maintained
        svg.style["max-width"]="100%";
  
        var div = document.createElement('div');
        div.style["text-align"]="center"; 
        div.appendChild(svg);
        return div;
      }, 
      
      
    });

</script>

<script>
addEventListener("load", function() {  SVGInject(document.querySelector("img.plantsvg")); })
</script>

You need to use the Markdown editor to get this working - Settings > Page Editor - Select Markdown
image

And then in your editor - paste the following - change the src to the path to your SVG file - in my case it is an attachment

image

  <img src="/attachments/10" class="plantsvg"  />

And the final result looks like this when you save

image

It is interactive - i.e. i can click links & select text

image

image

@HacKanCuBa
Copy link

I would love this fix too!
Does the fix mentioned above requires ALLOW_CONTENT_SCRIPTS to be true? cc @bharatrajagopalan

@WarriorXK
Copy link

Is there any indication that this would be added? I have a lot of diagrams and it would be amazing if we could retain the SVG quality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

7 participants