From 3e2cfeba3ad12f23a150934a2620cd8f98d64252 Mon Sep 17 00:00:00 2001 From: erwin-faceit <43995928+erwin-faceit@users.noreply.github.com> Date: Mon, 24 Jan 2022 15:54:09 +0100 Subject: [PATCH] Plantuml svg loader (#800) * Use svg-loader instead of img tag to preserve interactive diagrams * Configure img vs svg tag * Updated usage documentation and added default to config.toml Co-authored-by: Erwin Bovendeur Co-authored-by: LisaFC --- assets/js/plantuml.js | 11 ++++++++++- assets/vendor/bootstrap | 2 +- userguide/config.toml | 1 + .../Adding content/diagrams-and-formulae/index.md | 10 +++++++--- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/assets/js/plantuml.js b/assets/js/plantuml.js index 3cf7d2cfcc..26bac100c0 100644 --- a/assets/js/plantuml.js +++ b/assets/js/plantuml.js @@ -1,5 +1,10 @@ {{ with .Site.Params.plantuml }} {{ if .enable }} +{{ if .svg }} +// https://unpkg.com/external-svg-loader@1.3.4/svg-loader.min.js +(function(){function t(e,r,n){function s(i,a){if(!r[i]){if(!e[i]){var c="function"==typeof require&&require;if(!a&&c)return c(i,!0);if(o)return o(i,!0);var u=new Error("Cannot find module '"+i+"'");throw u.code="MODULE_NOT_FOUND",u}var l=r[i]={exports:{}};e[i][0].call(l.exports,(function(t){var r=e[i][1][t];return s(r||t)}),l,l.exports,t,e,r,n)}return r[i].exports}for(var o="function"==typeof require&&require,i=0;i{const n=/url\("?#([a-zA-Z-0-9][\w:.-]*)"?\)/g;const s=/#([a-zA-Z][\w:.-]*)/g;if(e.match(n)){e=e.replace(n,(function(e,r){if(!t[r]){return e}return`url(#${t[r]})`}))}if(["href","xlink:href"].includes(r)){if(e.match(s)){e=e.replace(s,(function(e,r){if(!t[r]){return e}return`#${t[r]}`}))}}return e}},{}],3:[function(t,e,r){"use strict";e.exports=(t,e)=>{const r=new RegExp("([^\r\n,{}]+)(,(?=[^}]*{)|s*{)","g");t=t.replace(r,(function(t,r,n){if(r.match(/^\s*(@media|@.*keyframes|to|from|@font-face|1?[0-9]?[0-9])/)){return r+n}r=r.replace(/^(\s*)/,"$1"+e+" ");return r+n}));return t}},{}],4:[function(t,e,r){"use strict";Object.defineProperty(r,"__esModule",{value:true});class n{constructor(t="keyval-store",e="keyval"){this.storeName=e;this._dbp=new Promise(((r,n)=>{const s=indexedDB.open(t,1);s.onerror=()=>n(s.error);s.onsuccess=()=>r(s.result);s.onupgradeneeded=()=>{s.result.createObjectStore(e)}}))}_withIDBStore(t,e){return this._dbp.then((r=>new Promise(((n,s)=>{const o=r.transaction(this.storeName,t);o.oncomplete=()=>n();o.onabort=o.onerror=()=>s(o.error);e(o.objectStore(this.storeName))}))))}}let s;function o(){if(!s)s=new n;return s}function i(t,e=o()){let r;return e._withIDBStore("readonly",(e=>{r=e.get(t)})).then((()=>r.result))}function a(t,e,r=o()){return r._withIDBStore("readwrite",(r=>{r.put(e,t)}))}function c(t,e=o()){return e._withIDBStore("readwrite",(e=>{e.delete(t)}))}function u(t=o()){return t._withIDBStore("readwrite",(t=>{t.clear()}))}function l(t=o()){const e=[];return t._withIDBStore("readonly",(t=>{(t.openKeyCursor||t.openCursor).call(t).onsuccess=function(){if(!this.result)return;e.push(this.result.key);this.result.continue()}})).then((()=>e))}r.Store=n;r.get=i;r.set=a;r.del=c;r.clear=u;r.keys=l},{}],5:[function(t,e,r){"use strict";const{get:n,set:s,del:o}=t("idb-keyval");const i=t("./lib/scope-css");const a=t("./lib/css-url-fixer");const c=t("./lib/counter");const u=async t=>{try{let e=await n(`loader_${t}`);if(!e){return}e=JSON.parse(e);if(Date.now(){try{const n=parseInt(r,10);await s(`loader_${t}`,JSON.stringify({data:e,expiry:Date.now()+(Number.isNaN(n)?60*60*1e3*24:n)}))}catch(t){console.error(t)}};const d=[];const f=()=>{if(d.length){return d}for(const t in document.head){if(t.startsWith("on")){d.push(t)}}return d};const b={};const h=(t,e,r)=>{const{enableJs:n,disableUniqueIds:s,disableCssScoping:o}=e;const u=new DOMParser;const l=u.parseFromString(r,"text/html");const d=l.querySelector("svg");const h=f();const g=b[t.getAttribute("data-id")]||new Set;const p=t.getAttribute("data-id")||`svg-loader_${c.incr()}`;const m={};if(!s){Array.from(l.querySelectorAll("[id]")).forEach((t=>{const e=t.getAttribute("id");const r=`${e}_${c.incr()}`;t.setAttribute("id",r);m[e]=r}))}Array.from(l.querySelectorAll("*")).forEach((t=>{if(t.tagName==="script"){if(!n){t.remove();return}else{const e=document.createElement("script");e.innerHTML=t.innerHTML;document.body.appendChild(e)}}for(let e=0;e{const e=t.getAttribute("data-src");const r=t.getAttribute("data-cache");const n=t.getAttribute("data-js")==="enabled";const s=t.getAttribute("data-unique-ids")==="disabled";const o=t.getAttribute("data-css-scoping")==="disabled";const i=await u(e);const a=r!=="disabled";const c=h.bind(this,t,{enableJs:n,disableUniqueIds:s,disableCssScoping:o});if(p[e]||a&&i){const t=p[e]||i;c(t)}else{if(g[e]){setTimeout((()=>m(t)),20);return}g[e]=true;fetch(e).then((t=>{if(!t.ok){throw Error(`Request for '${e}' returned ${t.status} (${t.statusText})`)}return t.text()})).then((t=>{const n=t.toLowerCase().trim();if(!(n.startsWith("{console.error(t)})).finally((()=>{delete g[e]}))}};let y;if(globalThis.IntersectionObserver){const t=new IntersectionObserver((e=>{e.forEach((e=>{if(e.isIntersecting){m(e.target);t.unobserve(e.target)}}))}),{rootMargin:"1200px"})}const v=[];function w(){Array.from(document.querySelectorAll("svg[data-src]:not([data-id])")).forEach((t=>{if(v.indexOf(t)!==-1){return}v.push(t);if(t.getAttribute("data-loading")==="lazy"){y.observe(t)}else{m(t)}}))}let A=false;const x=()=>{if(A){return}A=true;const t=new MutationObserver((t=>{const e=t.some((t=>Array.from(t.addedNodes).some((t=>t.nodeType===Node.ELEMENT_NODE&&(t.getAttribute("data-src")&&!t.getAttribute("data-id")||t.querySelector("svg[data-src]:not([data-id])"))))));if(e){w()}t.forEach((t=>{if(t.type==="attributes"){m(t.target)}}))}));t.observe(document.documentElement,{attributeFilter:["data-src"],attributes:true,childList:true,subtree:true})};if(globalThis.addEventListener){const t=setInterval((()=>{w()}),100);globalThis.addEventListener("DOMContentLoaded",(()=>{clearInterval(t);w();x()}))}},{"./lib/counter":1,"./lib/css-url-fixer":2,"./lib/scope-css":3,"idb-keyval":4}]},{},[5]); +{{ end }} + (function($) { function encode64(data) { @@ -55,7 +60,11 @@ var needPlantuml = false; $('.language-plantuml').parent().replaceWith(function() { let s = unescape(encodeURIComponent($(this).text())); - return $('') + {{ if .svg }} + return $('') + {{ else }} + return $('') + {{ end }} }); })(jQuery); {{ end }} diff --git a/assets/vendor/bootstrap b/assets/vendor/bootstrap index 043a03c95a..6ffb0b48e4 160000 --- a/assets/vendor/bootstrap +++ b/assets/vendor/bootstrap @@ -1 +1 @@ -Subproject commit 043a03c95a2ad6738f85b65e53b9dbdfb03b8d10 +Subproject commit 6ffb0b48e455430f8a5359ed689ad64c1143fac2 diff --git a/userguide/config.toml b/userguide/config.toml index 8fc8165f7e..7661151b77 100644 --- a/userguide/config.toml +++ b/userguide/config.toml @@ -219,6 +219,7 @@ theme = "default" enable = true theme = "default" svg_image_url = "https://www.plantuml.com/plantuml/svg/" +svg = false [params.katex] enable = true diff --git a/userguide/content/en/docs/Adding content/diagrams-and-formulae/index.md b/userguide/content/en/docs/Adding content/diagrams-and-formulae/index.md index 1e5363d9f4..49902acb20 100644 --- a/userguide/content/en/docs/Adding content/diagrams-and-formulae/index.md +++ b/userguide/content/en/docs/Adding content/diagrams-and-formulae/index.md @@ -211,7 +211,7 @@ entity entity as Foo4 database database as Foo5 collections collections as Foo6 queue queue as Foo7 -Foo -> Foo1 : To actor +Foo -> Foo1 : To actor Foo -> Foo2 : To boundary Foo -> Foo3 : To control Foo -> Foo4 : To entity @@ -232,7 +232,7 @@ entity entity as Foo4 database database as Foo5 collections collections as Foo6 queue queue as Foo7 -Foo -> Foo1 : To actor +Foo -> Foo1 : To actor Foo -> Foo2 : To boundary Foo -> Foo3 : To control Foo -> Foo4 : To entity @@ -254,10 +254,14 @@ Other optional settings are: enable = true theme = "default" -#Set url to plantuml server +#Set url to plantuml server #default is http://www.plantuml.com/plantuml/svg/ svg_image_url = "https://www.plantuml.com/plantuml/svg/" +#By default the plantuml implementation uses tags to display UML diagrams. +#When svg is set to true, diagrams are displayed using tags, maintaining functionality like links e.d. +#default = false +svg = true ``` ## MindMap support with MarkMap