From 407cd050aa91b6c773b76be6e8c06306724fb666 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Mon, 9 Dec 2024 15:59:47 +0000 Subject: [PATCH 01/12] Add tm-save-dom-to-image message --- .../geospatial/docs/save-dom-to-image.tid | 43 ++++++++++++++++++ .../files/dom-to-image-more/LICENSE | 29 ++++++++++++ .../dom-to-image-more.min.js | 3 ++ .../files/dom-to-image-more/tiddlywiki.files | 20 +++++++++ plugins/tiddlywiki/geospatial/readme.tid | 1 + plugins/tiddlywiki/geospatial/startup.js | 44 +++++++++++++++++++ 6 files changed, 140 insertions(+) create mode 100644 plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid create mode 100644 plugins/tiddlywiki/geospatial/files/dom-to-image-more/LICENSE create mode 100644 plugins/tiddlywiki/geospatial/files/dom-to-image-more/dom-to-image-more.min.js create mode 100644 plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files diff --git a/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid b/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid new file mode 100644 index 00000000000..434f923df2c --- /dev/null +++ b/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid @@ -0,0 +1,43 @@ +title: $:/plugins/tiddlywiki/geospatial/docs/save-dom-to-image +caption: tm-save-dom-to-image message +tags: $:/tags/GeospatialDocs + +!! `tm-save-dom-to-image` message + +The `tm-save-dom-to-image` message uses a [[third-party library|https://github.com/1904labs/dom-to-image-more]] to save a DOM node as an image. The image can be saved to a file or to a tiddler. + +Note that there are some limitations to saving content loaded from external domains due to the same-origin policy. See the documentation for more details. + +The following parameters are supported: + +|!Parameters |!Description | +|''selector'' |CSS selector identifying the DOM node to be saved as an image (defaults to `body`) | +|''format'' |Save format: ''png'', ''jpeg'' or ''svg'' (defaults to ''png'') | +|''quality'' |Optional quality 0 to 1 for JPEG images (defaults to 1) | +|''scale'' |Optional scale factor for the image (defaults to 1) | +|''width'' |Optional width of the image in pixels | +|''height'' |Optional height of the image in pixels | +|''save-file'' |Optional filename to save the image to | +|''save-title'' |Optional title of tiddler to save the image to | + +!! Examples + +<$button> +<$action-sendmessage + $message="tm-save-dom-to-image" + selector="body.tc-body" + scale="2" + save-file="screenshot.png" +/> +Save the screen as an image file + + +<$button> +<$action-sendmessage + $message="tm-save-dom-to-image" + selector="body.tc-body" + scale="2" + save-title="$:/temp/screenshot.png" +/> +Save the screen as an image tiddler + [[$:/temp/screenshot.png]] diff --git a/plugins/tiddlywiki/geospatial/files/dom-to-image-more/LICENSE b/plugins/tiddlywiki/geospatial/files/dom-to-image-more/LICENSE new file mode 100644 index 00000000000..f5855b1a374 --- /dev/null +++ b/plugins/tiddlywiki/geospatial/files/dom-to-image-more/LICENSE @@ -0,0 +1,29 @@ +The MIT License (MIT) + +Copyright 2018 Marc Brooks +https://about.me/idisposable + +Copyright 2015 Anatolii Saienko +https://github.com/tsayen + +Copyright 2012 Paul Bakaus +http://paulbakaus.com/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/plugins/tiddlywiki/geospatial/files/dom-to-image-more/dom-to-image-more.min.js b/plugins/tiddlywiki/geospatial/files/dom-to-image-more/dom-to-image-more.min.js new file mode 100644 index 00000000000..6be6a54eb59 --- /dev/null +++ b/plugins/tiddlywiki/geospatial/files/dom-to-image-more/dom-to-image-more.min.js @@ -0,0 +1,3 @@ +/*! dom-to-image-more 14-10-2024 */ +(l=>{let f=(()=>{let e=0;return{escape:function(e){return e.replace(/([.*+?^${}()|[\]/\\])/g,"\\$1")},isDataUrl:function(e){return-1!==e.search(/^(data:)/)},canvasToBlob:function(t){if(t.toBlob)return new Promise(function(e){t.toBlob(e)});return(r=>new Promise(function(e){var t=u(r.toDataURL().split(",")[1]),n=t.length,o=new Uint8Array(n);for(let e=0;e0<=s.search(e)).length),a.impl.options.useCredentials&&(r.withCredentials=!0),a.impl.options.corsImg&&0===s.indexOf("http")&&-1===s.indexOf(window.location.origin)){var i="POST"===(a.impl.options.corsImg.method||"GET").toUpperCase()?"POST":"GET";r.open(i,(a.impl.options.corsImg.url||"").replace("#{cors}",s),!0);let t=!1,n=a.impl.options.corsImg.headers||{},o=(Object.keys(n).forEach(function(e){-1!==n[e].indexOf("application/json")&&(t=!0),r.setRequestHeader(e,n[e])}),(e=>{try{return JSON.parse(JSON.stringify(e))}catch(e){l("corsImg.data is missing or invalid:"+e.toString())}})(a.impl.options.corsImg.data||""));Object.keys(o).forEach(function(e){"string"==typeof o[e]&&(o[e]=o[e].replace("#{cors}",s))}),r.send(t?JSON.stringify(o):o)}else r.open("GET",s,!0),r.send();let n;function l(e){console.error(e),t("")}a.impl.options.imagePlaceholder&&(i=a.impl.options.imagePlaceholder.split(/,/))&&i[1]&&(n=i[1])}));return e.promise},uid:function(){return"u"+("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)+e++},delay:function(n){return function(t){return new Promise(function(e){setTimeout(function(){e(t)},n)})}},asArray:function(t){var n=[],o=t.length;for(let e=0;e{document.body.removeChild(n),t(e)},n.appendChild(o),o.src=r,document.body.appendChild(n)}):Promise.resolve()},width:function(e){var t=i(e,"width");if(!isNaN(t))return t;var t=i(e,"border-left-width"),n=i(e,"border-right-width");return e.scrollWidth+t+n},height:function(e){var t=i(e,"height");if(!isNaN(t))return t;var t=i(e,"border-top-width"),n=i(e,"border-bottom-width");return e.scrollHeight+t+n},getWindow:t,isElement:r,isElementHostForOpenShadowRoot:function(e){return r(e)&&null!==e.shadowRoot},isShadowRoot:n,isInShadowRoot:o,isHTMLElement:function(e){return e instanceof t(e).HTMLElement},isHTMLCanvasElement:function(e){return e instanceof t(e).HTMLCanvasElement},isHTMLInputElement:function(e){return e instanceof t(e).HTMLInputElement},isHTMLImageElement:function(e){return e instanceof t(e).HTMLImageElement},isHTMLLinkElement:function(e){return e instanceof t(e).HTMLLinkElement},isHTMLScriptElement:function(e){return e instanceof t(e).HTMLScriptElement},isHTMLStyleElement:function(e){return e instanceof t(e).HTMLStyleElement},isHTMLTextAreaElement:function(e){return e instanceof t(e).HTMLTextAreaElement},isShadowSlotElement:function(e){return o(e)&&e instanceof t(e).HTMLSlotElement},isSVGElement:function(e){return e instanceof t(e).SVGElement},isSVGRectElement:function(e){return e instanceof t(e).SVGRectElement},isDimensionMissing:function(e){return isNaN(e)||e<=0}};function t(e){e=e?e.ownerDocument:void 0;return(e?e.defaultView:void 0)||window||l}function n(e){return e instanceof t(e).ShadowRoot}function o(e){return null!=e&&void 0!==e.getRootNode&&n(e.getRootNode())}function r(e){return e instanceof t(e).Element}function i(t,n){if(t.nodeType===c){let e=m(t).getPropertyValue(n);if("px"===e.slice(-2))return e=e.slice(0,-2),parseFloat(e)}return NaN}})(),r=(()=>{let o=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:function(t,o,r){if(!e(t))return Promise.resolve(t);return Promise.resolve(t).then(n).then(function(e){let n=Promise.resolve(t);return e.forEach(function(t){n=n.then(function(e){return i(e,t,o,r)})}),n})},shouldProcess:e,impl:{readUrls:n,inline:i}};function e(e){return-1!==e.search(o)}function n(e){for(var t,n=[];null!==(t=o.exec(e));)n.push(t[1]);return n.filter(function(e){return!f.isDataUrl(e)})}function i(n,o,t,e){return Promise.resolve(o).then(function(e){return t?f.resolveUrl(e,t):e}).then(e||f.getAndEncode).then(function(e){return n.replace((t=o,new RegExp(`(url\\(['"]?)(${f.escape(t)})(['"]?\\))`,"g")),`$1${e}$3`);var t})}})(),e={resolveAll:function(){return t().then(function(e){return Promise.all(e.map(function(e){return e.resolve()}))}).then(function(e){return e.join("\n")})},impl:{readAll:t}};function t(){return Promise.resolve(f.asArray(document.styleSheets)).then(function(e){let n=[];return e.forEach(function(t){var e=Object.getPrototypeOf(t);if(Object.prototype.hasOwnProperty.call(e,"cssRules"))try{f.asArray(t.cssRules||[]).forEach(n.push.bind(n))}catch(e){console.error("domtoimage: Error while reading CSS rules from "+t.href,e.toString())}}),n}).then(function(e){return e.filter(function(e){return e.type===CSSRule.FONT_FACE_RULE}).filter(function(e){return r.shouldProcess(e.style.getPropertyValue("src"))})}).then(function(e){return e.map(t)});function t(t){return{resolve:function(){var e=(t.parentStyleSheet||{}).href;return r.inlineAll(t.cssText,e)},src:function(){return t.style.getPropertyValue("src")}}}}let n={inlineAll:function t(e){if(!f.isElement(e))return Promise.resolve(e);return n(e).then(function(){return f.isHTMLImageElement(e)?o(e).inline():Promise.all(f.asArray(e.childNodes).map(function(e){return t(e)}))});function n(o){let e=["background","background-image"],t=e.map(function(t){let e=o.style.getPropertyValue(t),n=o.style.getPropertyPriority(t);return e?r.inlineAll(e).then(function(e){o.style.setProperty(t,e,n)}):Promise.resolve()});return Promise.all(t).then(function(){return o})}},impl:{newImage:o}};function o(n){return{inline:function(e){if(f.isDataUrl(n.src))return Promise.resolve();return Promise.resolve(n.src).then(e||f.getAndEncode).then(function(t){return new Promise(function(e){n.onload=e,n.onerror=e,n.src=t})})}}}let s={copyDefaultStyles:!0,imagePlaceholder:void 0,cacheBust:!1,useCredentials:!1,useCredentialsFilters:[],httpTimeout:3e4,styleCaching:"strict",corsImg:void 0,adjustClonedNode:void 0},a={toSvg:d,toPng:function(e,t){return i(e,t).then(function(e){return e.toDataURL()})},toJpeg:function(e,t){return i(e,t).then(function(e){return e.toDataURL("image/jpeg",(t?t.quality:void 0)||1)})},toBlob:function(e,t){return i(e,t).then(f.canvasToBlob)},toPixelData:function(t,e){return i(t,e).then(function(e){return e.getContext("2d").getImageData(0,0,f.width(t),f.height(t)).data})},toCanvas:i,impl:{fontFaces:e,images:n,util:f,inliner:r,urlCache:[],options:{}}},c=("object"==typeof exports&&"object"==typeof module?module.exports=a:l.domtoimage=a,("undefined"!=typeof Node?Node.ELEMENT_NODE:void 0)||1),m=(void 0!==l?l.getComputedStyle:void 0)||("undefined"!=typeof window?window.getComputedStyle:void 0)||globalThis.getComputedStyle,u=(void 0!==l?l.atob:void 0)||("undefined"!=typeof window?window.atob:void 0)||globalThis.atob;function d(e,r){let t=a.impl.util.getWindow(e);var n=r=r||{};void 0===n.copyDefaultStyles?a.impl.options.copyDefaultStyles=s.copyDefaultStyles:a.impl.options.copyDefaultStyles=n.copyDefaultStyles,a.impl.options.imagePlaceholder=(void 0===n.imagePlaceholder?s:n).imagePlaceholder,a.impl.options.cacheBust=(void 0===n.cacheBust?s:n).cacheBust,a.impl.options.corsImg=(void 0===n.corsImg?s:n).corsImg,a.impl.options.useCredentials=(void 0===n.useCredentials?s:n).useCredentials,a.impl.options.useCredentialsFilters=(void 0===n.useCredentialsFilters?s:n).useCredentialsFilters,a.impl.options.httpTimeout=(void 0===n.httpTimeout?s:n).httpTimeout,a.impl.options.styleCaching=(void 0===n.styleCaching?s:n).styleCaching;let i=[];return Promise.resolve(e).then(function(e){if(e.nodeType===c)return e;var t=e,n=e.parentNode,o=document.createElement("span");return n.replaceChild(o,t),o.append(e),i.push({parent:n,child:t,wrapper:o}),o}).then(function(e){return function l(t,s,r,u){let e=s.filter;if(t===h||f.isHTMLScriptElement(t)||f.isHTMLStyleElement(t)||f.isHTMLLinkElement(t)||null!==r&&e&&!e(t))return Promise.resolve();return Promise.resolve(t).then(n).then(o).then(function(e){return c(e,a(t))}).then(i).then(function(e){return d(e,t)});function n(e){return f.isHTMLCanvasElement(e)?f.makeImage(e.toDataURL()):e.cloneNode(!1)}function o(e){return s.adjustClonedNode&&s.adjustClonedNode(t,e,!1),Promise.resolve(e)}function i(e){return s.adjustClonedNode&&s.adjustClonedNode(t,e,!0),Promise.resolve(e)}function a(e){return f.isElementHostForOpenShadowRoot(e)?e.shadowRoot:e}function c(n,e){let o=t(e),r=Promise.resolve();if(0!==o.length){let t=m(i(e));f.asArray(o).forEach(function(e){r=r.then(function(){return l(e,s,t,u).then(function(e){e&&n.appendChild(e)})})})}return r.then(function(){return n});function i(e){return f.isShadowRoot(e)?e.host:e}function t(t){if(f.isShadowSlotElement(t)){let e=t.assignedNodes();if(e&&0t.style.removeProperty(e)),["left","right","top","bottom"].forEach(e=>{t.style.getPropertyValue(e)&&t.style.setProperty(e,"0px")})))}e(a,u)}function t(){let s=f.uid();function t(r){let i=m(a,r),l=i.getPropertyValue("content");if(""!==l&&"none"!==l){let e=u.getAttribute("class")||"",t=(u.setAttribute("class",e+" "+s),document.createElement("style"));function n(){let e=`.${s}:`+r,t=(i.cssText?n:o)();return document.createTextNode(e+`{${t}}`);function n(){return`${i.cssText} content: ${l};`}function o(){let e=f.asArray(i).map(t).join("; ");return e+";";function t(e){let t=i.getPropertyValue(e),n=i.getPropertyPriority(e)?" !important":"";return e+": "+t+n}}}t.appendChild(n()),u.appendChild(t)}}[":before",":after"].forEach(function(e){t(e)})}function n(){f.isHTMLTextAreaElement(a)&&(u.innerHTML=a.value),f.isHTMLInputElement(a)&&u.setAttribute("value",a.value)}function o(){f.isSVGElement(u)&&(u.setAttribute("xmlns","http://www.w3.org/2000/svg"),f.isSVGRectElement(u))&&["width","height"].forEach(function(e){let t=u.getAttribute(e);t&&u.style.setProperty(e,t)})}}}(e,r,null,t)}).then(r.disableEmbedFonts?Promise.resolve(e):p).then(g).then(function(t){r.bgcolor&&(t.style.backgroundColor=r.bgcolor);r.width&&(t.style.width=r.width+"px");r.height&&(t.style.height=r.height+"px");r.style&&Object.keys(r.style).forEach(function(e){t.style[e]=r.style[e]});let e=null;"function"==typeof r.onclone&&(e=r.onclone(t));return Promise.resolve(e).then(function(){return t})}).then(function(e){let n=r.width||f.width(e),o=r.height||f.height(e);return Promise.resolve(e).then(function(e){return e.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(e)}).then(f.escapeXhtml).then(function(e){var t=(f.isDimensionMissing(n)?' width="100%"':` width="${n}"`)+(f.isDimensionMissing(o)?' height="100%"':` height="${o}"`);return`${e}`}).then(function(e){return"data:image/svg+xml;charset=utf-8,"+e})}).then(function(e){for(;0{h&&(document.body.removeChild(h),h=null),v&&clearTimeout(v),v=setTimeout(()=>{v=null,w={}},2e4)})(),e})}function i(r,i){return d(r,i=i||{}).then(f.makeImage).then(function(e){var t="number"!=typeof i.scale?1:i.scale,n=((e,t)=>{let n=i.width||f.width(e),o=i.height||f.height(e);return f.isDimensionMissing(n)&&(n=f.isDimensionMissing(o)?300:2*o),f.isDimensionMissing(o)&&(o=n/2),(e=document.createElement("canvas")).width=n*t,e.height=o*t,i.bgcolor&&((t=e.getContext("2d")).fillStyle=i.bgcolor,t.fillRect(0,0,e.width,e.height)),e})(r,t),o=n.getContext("2d");return o.msImageSmoothingEnabled=!1,o.imageSmoothingEnabled=!1,e&&(o.scale(t,t),o.drawImage(e,0,0)),n})}let h=null;function p(n){return e.resolveAll().then(function(e){var t;return""!==e&&(t=document.createElement("style"),n.appendChild(t),t.appendChild(document.createTextNode(e))),n})}function g(e){return n.inlineAll(e).then(function(){return e})}function y(e,t,i,l,n){let s=a.impl.options.copyDefaultStyles?((t,e)=>{var n,o=(e=>("relaxed"!==t.styleCaching?e:e.filter((e,t,n)=>0===t||t===n.length-1)).join(">"))(e=(e=>{var t=[];do{if(e.nodeType===c){var n=e.tagName;if(t.push(n),E.includes(n))break}}while(e=e.parentNode);return t})(e));{if(w[o])return w[o];e=((e,t)=>{let n=e.body;do{var o=t.pop(),o=e.createElement(o);n.appendChild(o),n=o}while(0{if(h)return h.contentWindow;t=document.characterSet||"UTF-8",e=(e=document.doctype)?(`":"",(h=document.createElement("iframe")).id="domtoimage-sandbox-"+f.uid(),h.style.visibility="hidden",h.style.position="fixed",document.body.appendChild(h);var e,t,n=h,o="domtoimage-sandbox";try{return n.contentWindow.document.write(e+`${o}`),n.contentWindow}catch(e){}var r=document.createElement("meta");r.setAttribute("charset",t);try{var i=document.implementation.createHTMLDocument(o),l=(i.head.appendChild(r),e+i.documentElement.outerHTML);return n.setAttribute("srcdoc",l),n.contentWindow}catch(e){}return n.contentDocument.head.appendChild(r),n.contentDocument.title=o,n.contentWindow;function s(e){var t;return e?((t=document.createElement("div")).innerText=e,t.innerHTML):""}})()).document,e),n=((e,t)=>{let n={},o=e.getComputedStyle(t);return f.asArray(o).forEach(function(e){n[e]="width"===e||"height"===e?"auto":o.getPropertyValue(e)}),n})(n,e);var r=e;do{var i=r.parentElement;null!==i&&i.removeChild(r),r=i}while(r&&"BODY"!==r.tagName);return w[o]=n}})(e,t):{},u=n.style;f.asArray(i).forEach(function(e){var t,n=i.getPropertyValue(e),o=s[e],r=l?l.getPropertyValue(e):void 0;u.getPropertyValue(e)||(n!==o||l&&n!==r)&&(o=i.getPropertyPriority(e),r=u,n=n,o=o,t=0<=["background-clip"].indexOf(e=e),o?(r.setProperty(e,n,o),t&&r.setProperty("-webkit-"+e,n,o)):(r.setProperty(e,n),t&&r.setProperty("-webkit-"+e,n)))})}let v=null,w={},E=["ADDRESS","ARTICLE","ASIDE","BLOCKQUOTE","DETAILS","DIALOG","DD","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","H1","H2","H3","H4","H5","H6","HEADER","HGROUP","HR","LI","MAIN","NAV","OL","P","PRE","SECTION","SVG","TABLE","UL","math","svg","BODY","HEAD","HTML"]})(this); +//# sourceMappingURL=dom-to-image-more.min.js.map \ No newline at end of file diff --git a/plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files b/plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files new file mode 100644 index 00000000000..007e9e7df41 --- /dev/null +++ b/plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files @@ -0,0 +1,20 @@ +{ + "tiddlers": [ + { + "file": "dom-to-image-more.min.js", + "fields": { + "type": "application/javascript", + "title": "$:/plugins/tiddlywiki/geospatial/dom-to-image-more.js", + "module-type": "library", + "url": "https://github.com/1904labs/dom-to-image-more" + } + }, + { + "file": "LICENSE", + "fields": { + "type": "text/plain", + "title": "$:/plugins/tiddlywiki/geospatial/dom-to-image-more/LICENSE" + } + } + ] +} diff --git a/plugins/tiddlywiki/geospatial/readme.tid b/plugins/tiddlywiki/geospatial/readme.tid index df8576218f1..8dab3bbb0cd 100644 --- a/plugins/tiddlywiki/geospatial/readme.tid +++ b/plugins/tiddlywiki/geospatial/readme.tid @@ -11,3 +11,4 @@ The Geospatial Plugin incorporates a number of third party libraries and online * [[TravelTime|https://traveltime.com/]], a commercial API for [[geocoding|https://traveltime.com/features/geocoding]], [[routing|https://traveltime.com/features/multi-modal-routing]] and [[isochrones|https://traveltime.com/features/isochrones]] * [[Flickr|https://www.flickr.com/services/api/]], a free API for retrieving geotagged photographs * [[OpenLocationCode|https://github.com/google/open-location-code]], Google's open source library for converting to and from Open Location Codes (also known as [[PlusCodes|https://maps.google.com/pluscodes/]]) +* [[dom-to-image-more|https://github.com/1904labs/dom-to-image-more]], an open source library for saving web content as images diff --git a/plugins/tiddlywiki/geospatial/startup.js b/plugins/tiddlywiki/geospatial/startup.js index 1b76e9949ec..690a49d63b8 100644 --- a/plugins/tiddlywiki/geospatial/startup.js +++ b/plugins/tiddlywiki/geospatial/startup.js @@ -28,6 +28,50 @@ exports.startup = function() { require("$:/plugins/tiddlywiki/geospatial/leaflet.markercluster.js"); } // Install geolocation message handler + $tw.rootWidget.addEventListener("tm-save-dom-to-image",function(event) { + var params = event.paramObject || {}, + domToImage = require("$:/plugins/tiddlywiki/geospatial/dom-to-image-more.js"), + domNode = document.querySelector(params.selector || "body.tc-body"); + if(domNode) { + var method = "toPng"; + switch(params.format) { + case "jpeg": + method = "toJpeg"; + break; + case "svg": + method = "toSvg"; + break; + } + domToImage[method](domNode,{ + height: $tw.utils.parseInt(params.height) || domNode.offsetHeight, + width: $tw.utils.parseInt(params.width) || domNode.offsetWidth, + quality: $tw.utils.parseNumber(params.quality), + scale: $tw.utils.parseNumber(params.scale) + }) + .then(function(dataUrl) { + // Save the image + if(params["save-file"]) { + var link = document.createElement("a"); + link.download = params["save-file"]; + link.href = dataUrl; + link.click(); + } + // Save the tiddler + if(params["save-title"]) { + var parts = dataUrl.split(";base64,"); + $tw.wiki.addTiddler(new $tw.Tiddler({ + title: params["save-title"], + type: parts[0].split(":")[1], + "text": parts[1] + })); + } + }) + .catch(function(error) { + console.error('oops, something went wrong!', error); + }); + } + }); + // Install geolocation message handler $tw.rootWidget.addEventListener("tm-request-geolocation",function(event) { var widget = event.widget, wiki = widget.wiki || $tw.wiki, From 9fb763f9914e9c62cc994bd32f3babbe8ad4b7cc Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Mon, 9 Dec 2024 16:00:06 +0000 Subject: [PATCH 02/12] Temporarily include the geospatial plugin in the Netlify previews --- editions/tw5.com/tiddlywiki.info | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/editions/tw5.com/tiddlywiki.info b/editions/tw5.com/tiddlywiki.info index 2f3ddade89c..a08cf88763e 100644 --- a/editions/tw5.com/tiddlywiki.info +++ b/editions/tw5.com/tiddlywiki.info @@ -7,7 +7,8 @@ "tiddlywiki/menubar", "tiddlywiki/confetti", "tiddlywiki/dynannotate", - "tiddlywiki/tour" + "tiddlywiki/tour", + "tiddlywiki/geospatial" ], "themes": [ "tiddlywiki/vanilla", From 2c271077aa7dccc9807d80945573927674dcfb63 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 10 Dec 2024 09:13:29 +0000 Subject: [PATCH 03/12] Scale should default to 1x --- plugins/tiddlywiki/geospatial/startup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/tiddlywiki/geospatial/startup.js b/plugins/tiddlywiki/geospatial/startup.js index 690a49d63b8..0ccc02b0ea4 100644 --- a/plugins/tiddlywiki/geospatial/startup.js +++ b/plugins/tiddlywiki/geospatial/startup.js @@ -46,7 +46,7 @@ exports.startup = function() { height: $tw.utils.parseInt(params.height) || domNode.offsetHeight, width: $tw.utils.parseInt(params.width) || domNode.offsetWidth, quality: $tw.utils.parseNumber(params.quality), - scale: $tw.utils.parseNumber(params.scale) + scale: $tw.utils.parseNumber(params.scale) || 1 }) .then(function(dataUrl) { // Save the image From c9ce9b192daf286a7c409700f3a9d8f0fcc5dac7 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 10 Dec 2024 09:23:53 +0000 Subject: [PATCH 04/12] Fix saving SVG images --- plugins/tiddlywiki/geospatial/startup.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/plugins/tiddlywiki/geospatial/startup.js b/plugins/tiddlywiki/geospatial/startup.js index 0ccc02b0ea4..df977c21559 100644 --- a/plugins/tiddlywiki/geospatial/startup.js +++ b/plugins/tiddlywiki/geospatial/startup.js @@ -58,12 +58,21 @@ exports.startup = function() { } // Save the tiddler if(params["save-title"]) { - var parts = dataUrl.split(";base64,"); - $tw.wiki.addTiddler(new $tw.Tiddler({ - title: params["save-title"], - type: parts[0].split(":")[1], - "text": parts[1] - })); + if(dataUrl.indexOf("data:image/svg+xml;") === 0) { + var commaIndex = dataUrl.indexOf(","); + $tw.wiki.addTiddler(new $tw.Tiddler({ + title: params["save-title"], + type: "image/svg+xml", + "text": decodeURIComponent(dataUrl.substring(commaIndex + 1)) + })); + } else { + var parts = dataUrl.split(";base64,"); + $tw.wiki.addTiddler(new $tw.Tiddler({ + title: params["save-title"], + type: parts[0].split(":")[1], + "text": parts[1] + })); + } } }) .catch(function(error) { From f36b9f248c1ce420c3a4157ebd56e4337636037a Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 10 Dec 2024 09:29:24 +0000 Subject: [PATCH 05/12] Add example of saving in SVG format --- .../tiddlywiki/geospatial/docs/save-dom-to-image.tid | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid b/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid index 434f923df2c..fa058b2a5e0 100644 --- a/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid +++ b/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid @@ -41,3 +41,13 @@ Save the screen as an image file /> Save the screen as an image tiddler [[$:/temp/screenshot.png]] + +<$button> +<$action-sendmessage + $message="tm-save-dom-to-image" + selector="body.tc-body" + format="svg" + save-title="$:/temp/screenshot.svg" +/> +Save the screen as an image tiddler in SVG format + [[$:/temp/screenshot.svg]] From fd21908896461d45a1730b9b6f2813b3fee40bb2 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 10 Dec 2024 12:47:18 +0000 Subject: [PATCH 06/12] Add library version number --- .../geospatial/files/dom-to-image-more/tiddlywiki.files | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files b/plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files index 007e9e7df41..f6069d217c9 100644 --- a/plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files +++ b/plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files @@ -6,7 +6,8 @@ "type": "application/javascript", "title": "$:/plugins/tiddlywiki/geospatial/dom-to-image-more.js", "module-type": "library", - "url": "https://github.com/1904labs/dom-to-image-more" + "url": "https://github.com/1904labs/dom-to-image-more", + "version": "3.5.0" } }, { From 4eed4cbaa53650db99562eb87785f6450c75ef72 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 10 Dec 2024 12:47:40 +0000 Subject: [PATCH 07/12] Document peculiarities of JPEG quality parameter --- .../geospatial/docs/save-dom-to-image.tid | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid b/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid index fa058b2a5e0..f3f17c0453c 100644 --- a/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid +++ b/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid @@ -13,7 +13,7 @@ The following parameters are supported: |!Parameters |!Description | |''selector'' |CSS selector identifying the DOM node to be saved as an image (defaults to `body`) | |''format'' |Save format: ''png'', ''jpeg'' or ''svg'' (defaults to ''png'') | -|''quality'' |Optional quality 0 to 1 for JPEG images (defaults to 1) | +|''quality'' |Optional quality 0 to 1 for JPEG images (note that the default quality is 1, and this default is applied even if the quality is explicitly specified as `0`. To force a low quality JPEG image it is therefore necessary to specify a small non-zero value such as `0.001`) | |''scale'' |Optional scale factor for the image (defaults to 1) | |''width'' |Optional width of the image in pixels | |''height'' |Optional height of the image in pixels | @@ -29,7 +29,7 @@ The following parameters are supported: scale="2" save-file="screenshot.png" /> -Save the screen as an image file +Save the screen as an image file in PNG format <$button> @@ -39,9 +39,21 @@ Save the screen as an image file scale="2" save-title="$:/temp/screenshot.png" /> -Save the screen as an image tiddler +Save the screen as an image tiddler in PNG format [[$:/temp/screenshot.png]] +<$button> +<$action-sendmessage + $message="tm-save-dom-to-image" + selector="body.tc-body" + format="jpeg" + scale="1" + quality="0.01" + save-title="$:/temp/screenshot.jpeg" +/> +Save the screen as an image tiddler in low quality JPEG format + [[$:/temp/screenshot.jpeg]] + <$button> <$action-sendmessage $message="tm-save-dom-to-image" From 925d3b0b4c301e57135fe61706af3377e6f2ccdb Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 10 Dec 2024 12:48:04 +0000 Subject: [PATCH 08/12] Allow format="jpg" as well as the more technically correct "jpeg" --- plugins/tiddlywiki/geospatial/startup.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/tiddlywiki/geospatial/startup.js b/plugins/tiddlywiki/geospatial/startup.js index df977c21559..dba705da502 100644 --- a/plugins/tiddlywiki/geospatial/startup.js +++ b/plugins/tiddlywiki/geospatial/startup.js @@ -36,6 +36,8 @@ exports.startup = function() { var method = "toPng"; switch(params.format) { case "jpeg": + // Intentional fallthrough + case "jpg": method = "toJpeg"; break; case "svg": From 6e1b58fca7cc026f9671fcb04a4d8d125b522045 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Tue, 10 Dec 2024 12:49:55 +0000 Subject: [PATCH 09/12] Document what happens if the selector returns multiple DOM nodes --- plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid b/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid index f3f17c0453c..8d17a0a42c1 100644 --- a/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid +++ b/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid @@ -11,7 +11,7 @@ Note that there are some limitations to saving content loaded from external doma The following parameters are supported: |!Parameters |!Description | -|''selector'' |CSS selector identifying the DOM node to be saved as an image (defaults to `body`) | +|''selector'' |CSS selector identifying the DOM node to be saved as an image (defaults to `body`). If multiple DOM nodes are returned by the selector then the first one is used | |''format'' |Save format: ''png'', ''jpeg'' or ''svg'' (defaults to ''png'') | |''quality'' |Optional quality 0 to 1 for JPEG images (note that the default quality is 1, and this default is applied even if the quality is explicitly specified as `0`. To force a low quality JPEG image it is therefore necessary to specify a small non-zero value such as `0.001`) | |''scale'' |Optional scale factor for the image (defaults to 1) | From 42b79213dd04fe45bc72ee9ca33ba693127224bd Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 11 Dec 2024 13:58:50 +0000 Subject: [PATCH 10/12] Refactor image-to-dom to be a separate plugin --- editions/tw5.com/tiddlywiki.info | 2 +- .../docs.tid} | 3 +- .../files}/LICENSE | 0 .../files}/dom-to-image-more.min.js | 0 .../files}/tiddlywiki.files | 4 +- plugins/tiddlywiki/dom-to-image/plugin.info | 7 ++ plugins/tiddlywiki/dom-to-image/readme.tid | 3 + plugins/tiddlywiki/dom-to-image/startup.js | 78 +++++++++++++++++++ plugins/tiddlywiki/geospatial/readme.tid | 1 - 9 files changed, 92 insertions(+), 6 deletions(-) rename plugins/tiddlywiki/{geospatial/docs/save-dom-to-image.tid => dom-to-image/docs.tid} (96%) rename plugins/tiddlywiki/{geospatial/files/dom-to-image-more => dom-to-image/files}/LICENSE (100%) rename plugins/tiddlywiki/{geospatial/files/dom-to-image-more => dom-to-image/files}/dom-to-image-more.min.js (100%) rename plugins/tiddlywiki/{geospatial/files/dom-to-image-more => dom-to-image/files}/tiddlywiki.files (68%) create mode 100644 plugins/tiddlywiki/dom-to-image/plugin.info create mode 100644 plugins/tiddlywiki/dom-to-image/readme.tid create mode 100644 plugins/tiddlywiki/dom-to-image/startup.js diff --git a/editions/tw5.com/tiddlywiki.info b/editions/tw5.com/tiddlywiki.info index a08cf88763e..af3a694b101 100644 --- a/editions/tw5.com/tiddlywiki.info +++ b/editions/tw5.com/tiddlywiki.info @@ -8,7 +8,7 @@ "tiddlywiki/confetti", "tiddlywiki/dynannotate", "tiddlywiki/tour", - "tiddlywiki/geospatial" + "tiddlywiki/dom-to-image" ], "themes": [ "tiddlywiki/vanilla", diff --git a/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid b/plugins/tiddlywiki/dom-to-image/docs.tid similarity index 96% rename from plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid rename to plugins/tiddlywiki/dom-to-image/docs.tid index 8d17a0a42c1..095406477e0 100644 --- a/plugins/tiddlywiki/geospatial/docs/save-dom-to-image.tid +++ b/plugins/tiddlywiki/dom-to-image/docs.tid @@ -1,6 +1,5 @@ -title: $:/plugins/tiddlywiki/geospatial/docs/save-dom-to-image +title: $:/plugins/tiddlywiki/dom-to-image/docs caption: tm-save-dom-to-image message -tags: $:/tags/GeospatialDocs !! `tm-save-dom-to-image` message diff --git a/plugins/tiddlywiki/geospatial/files/dom-to-image-more/LICENSE b/plugins/tiddlywiki/dom-to-image/files/LICENSE similarity index 100% rename from plugins/tiddlywiki/geospatial/files/dom-to-image-more/LICENSE rename to plugins/tiddlywiki/dom-to-image/files/LICENSE diff --git a/plugins/tiddlywiki/geospatial/files/dom-to-image-more/dom-to-image-more.min.js b/plugins/tiddlywiki/dom-to-image/files/dom-to-image-more.min.js similarity index 100% rename from plugins/tiddlywiki/geospatial/files/dom-to-image-more/dom-to-image-more.min.js rename to plugins/tiddlywiki/dom-to-image/files/dom-to-image-more.min.js diff --git a/plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files b/plugins/tiddlywiki/dom-to-image/files/tiddlywiki.files similarity index 68% rename from plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files rename to plugins/tiddlywiki/dom-to-image/files/tiddlywiki.files index f6069d217c9..316100c6d1d 100644 --- a/plugins/tiddlywiki/geospatial/files/dom-to-image-more/tiddlywiki.files +++ b/plugins/tiddlywiki/dom-to-image/files/tiddlywiki.files @@ -4,7 +4,7 @@ "file": "dom-to-image-more.min.js", "fields": { "type": "application/javascript", - "title": "$:/plugins/tiddlywiki/geospatial/dom-to-image-more.js", + "title": "$:/plugins/tiddlywiki/dom-to-image/dom-to-image-more.js", "module-type": "library", "url": "https://github.com/1904labs/dom-to-image-more", "version": "3.5.0" @@ -14,7 +14,7 @@ "file": "LICENSE", "fields": { "type": "text/plain", - "title": "$:/plugins/tiddlywiki/geospatial/dom-to-image-more/LICENSE" + "title": "$:/plugins/tiddlywiki/dom-to-image/dom-to-image-more/LICENSE" } } ] diff --git a/plugins/tiddlywiki/dom-to-image/plugin.info b/plugins/tiddlywiki/dom-to-image/plugin.info new file mode 100644 index 00000000000..00c1d740cbf --- /dev/null +++ b/plugins/tiddlywiki/dom-to-image/plugin.info @@ -0,0 +1,7 @@ +{ + "title": "$:/plugins/tiddlywiki/dom-to-image", + "name": "Dom-to-image", + "description": "Save DOM nodes as images", + "list": "readme docs", + "stability": "STABILITY_1_EXPERIMENTAL" +} diff --git a/plugins/tiddlywiki/dom-to-image/readme.tid b/plugins/tiddlywiki/dom-to-image/readme.tid new file mode 100644 index 00000000000..bb041ba4a2e --- /dev/null +++ b/plugins/tiddlywiki/dom-to-image/readme.tid @@ -0,0 +1,3 @@ +title: $:/plugins/tiddlywiki/dom-to-image/readme + +* [[dom-to-image-more|https://github.com/1904labs/dom-to-image-more]], an open source library for saving web content as images \ No newline at end of file diff --git a/plugins/tiddlywiki/dom-to-image/startup.js b/plugins/tiddlywiki/dom-to-image/startup.js new file mode 100644 index 00000000000..adc2ca65d40 --- /dev/null +++ b/plugins/tiddlywiki/dom-to-image/startup.js @@ -0,0 +1,78 @@ +/*\ +title: $:/plugins/tiddlywiki/dom-to-image/startup.js +type: application/javascript +module-type: startup + +dom-to-image initialisation + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +// Export name and synchronous status +exports.name = "dom-to-image"; +exports.after = ["rootwidget"]; +exports.before = ["render"]; +exports.synchronous = true; + +exports.startup = function() { + $tw.rootWidget.addEventListener("tm-save-dom-to-image",function(event) { + var params = event.paramObject || {}, + domToImage = require("$:/plugins/tiddlywiki/dom-to-image/dom-to-image-more.js"), + domNode = document.querySelector(params.selector || "body.tc-body"); + if(domNode) { + var method = "toPng"; + switch(params.format) { + case "jpeg": + // Intentional fallthrough + case "jpg": + method = "toJpeg"; + break; + case "svg": + method = "toSvg"; + break; + } + domToImage[method](domNode,{ + height: $tw.utils.parseInt(params.height) || domNode.offsetHeight, + width: $tw.utils.parseInt(params.width) || domNode.offsetWidth, + quality: $tw.utils.parseNumber(params.quality), + scale: $tw.utils.parseNumber(params.scale) || 1 + }) + .then(function(dataUrl) { + // Save the image + if(params["save-file"]) { + var link = document.createElement("a"); + link.download = params["save-file"]; + link.href = dataUrl; + link.click(); + } + // Save the tiddler + if(params["save-title"]) { + if(dataUrl.indexOf("data:image/svg+xml;") === 0) { + var commaIndex = dataUrl.indexOf(","); + $tw.wiki.addTiddler(new $tw.Tiddler({ + title: params["save-title"], + type: "image/svg+xml", + "text": decodeURIComponent(dataUrl.substring(commaIndex + 1)) + })); + } else { + var parts = dataUrl.split(";base64,"); + $tw.wiki.addTiddler(new $tw.Tiddler({ + title: params["save-title"], + type: parts[0].split(":")[1], + "text": parts[1] + })); + } + } + }) + .catch(function(error) { + console.error('oops, something went wrong!', error); + }); + } + }); +}; + +})(); diff --git a/plugins/tiddlywiki/geospatial/readme.tid b/plugins/tiddlywiki/geospatial/readme.tid index 8dab3bbb0cd..df8576218f1 100644 --- a/plugins/tiddlywiki/geospatial/readme.tid +++ b/plugins/tiddlywiki/geospatial/readme.tid @@ -11,4 +11,3 @@ The Geospatial Plugin incorporates a number of third party libraries and online * [[TravelTime|https://traveltime.com/]], a commercial API for [[geocoding|https://traveltime.com/features/geocoding]], [[routing|https://traveltime.com/features/multi-modal-routing]] and [[isochrones|https://traveltime.com/features/isochrones]] * [[Flickr|https://www.flickr.com/services/api/]], a free API for retrieving geotagged photographs * [[OpenLocationCode|https://github.com/google/open-location-code]], Google's open source library for converting to and from Open Location Codes (also known as [[PlusCodes|https://maps.google.com/pluscodes/]]) -* [[dom-to-image-more|https://github.com/1904labs/dom-to-image-more]], an open source library for saving web content as images From ed53a8d58060c45bacbb446026ab9e499349be36 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Wed, 18 Dec 2024 19:24:55 +0000 Subject: [PATCH 11/12] Add support for oncompletion handler --- plugins/tiddlywiki/dom-to-image/docs.tid | 2 ++ plugins/tiddlywiki/dom-to-image/startup.js | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/plugins/tiddlywiki/dom-to-image/docs.tid b/plugins/tiddlywiki/dom-to-image/docs.tid index 095406477e0..5183e97589e 100644 --- a/plugins/tiddlywiki/dom-to-image/docs.tid +++ b/plugins/tiddlywiki/dom-to-image/docs.tid @@ -18,6 +18,8 @@ The following parameters are supported: |''height'' |Optional height of the image in pixels | |''save-file'' |Optional filename to save the image to | |''save-title'' |Optional title of tiddler to save the image to | +|''oncompletion'' |Optional action string to be invoked when the save operation has completed | +|''var-*'' |Variables to be passed to the completion handler (without the "var-" prefix) | !! Examples diff --git a/plugins/tiddlywiki/dom-to-image/startup.js b/plugins/tiddlywiki/dom-to-image/startup.js index adc2ca65d40..4584752b8c8 100644 --- a/plugins/tiddlywiki/dom-to-image/startup.js +++ b/plugins/tiddlywiki/dom-to-image/startup.js @@ -19,10 +19,22 @@ exports.before = ["render"]; exports.synchronous = true; exports.startup = function() { + var getPropertiesWithPrefix = function(properties,prefix) { + var result = Object.create(null); + $tw.utils.each(properties,function(value,name) { + if(name.indexOf(prefix) === 0) { + result[name.substring(prefix.length)] = properties[name]; + } + }); + return result; + }; $tw.rootWidget.addEventListener("tm-save-dom-to-image",function(event) { + var self=this; /* ELS */ var params = event.paramObject || {}, domToImage = require("$:/plugins/tiddlywiki/dom-to-image/dom-to-image-more.js"), - domNode = document.querySelector(params.selector || "body.tc-body"); + domNode = document.querySelector(params.selector || "body.tc-body"), + oncompletion = params.oncompletion, + variables = getPropertiesWithPrefix(params,"var-"); if(domNode) { var method = "toPng"; switch(params.format) { @@ -67,6 +79,7 @@ exports.startup = function() { })); } } + self.wiki.invokeActionString(oncompletion,self,variables,{parentWidget: $tw.rootWidget}); }) .catch(function(error) { console.error('oops, something went wrong!', error); @@ -76,3 +89,4 @@ exports.startup = function() { }; })(); + \ No newline at end of file From 9aa65564d4d41177da326fde76d8f1db3b058e34 Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Thu, 19 Dec 2024 09:44:37 +0000 Subject: [PATCH 12/12] Remove ELS marker Thanks @ericshulman --- plugins/tiddlywiki/dom-to-image/startup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/tiddlywiki/dom-to-image/startup.js b/plugins/tiddlywiki/dom-to-image/startup.js index 4584752b8c8..516b7c8c715 100644 --- a/plugins/tiddlywiki/dom-to-image/startup.js +++ b/plugins/tiddlywiki/dom-to-image/startup.js @@ -29,8 +29,8 @@ exports.startup = function() { return result; }; $tw.rootWidget.addEventListener("tm-save-dom-to-image",function(event) { - var self=this; /* ELS */ - var params = event.paramObject || {}, + var self=this, + params = event.paramObject || {}, domToImage = require("$:/plugins/tiddlywiki/dom-to-image/dom-to-image-more.js"), domNode = document.querySelector(params.selector || "body.tc-body"), oncompletion = params.oncompletion,