From 810563b3f998cfa6b9721f72d75ce9ad6890fa7b Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 26 Jan 2026 19:21:19 +0200 Subject: [PATCH 1/9] fix(web-clipper): duplicate context menu error --- .../entrypoints/background/context_menu.ts | 42 +++++++++++++++++++ .../entrypoints/background/index.ts | 39 ++--------------- 2 files changed, 45 insertions(+), 36 deletions(-) create mode 100644 apps/web-clipper/entrypoints/background/context_menu.ts diff --git a/apps/web-clipper/entrypoints/background/context_menu.ts b/apps/web-clipper/entrypoints/background/context_menu.ts new file mode 100644 index 0000000000..6685651fbd --- /dev/null +++ b/apps/web-clipper/entrypoints/background/context_menu.ts @@ -0,0 +1,42 @@ +const CONTEXT_MENU_ITEMS: Browser.contextMenus.CreateProperties[] = [ + { + id: "trilium-save-selection", + title: "Save selection to Trilium", + contexts: ["selection"] + }, + { + id: "trilium-save-cropped-screenshot", + title: "Crop screen shot to Trilium", + contexts: ["page"] + }, + { + id: "trilium-save-whole-screenshot", + title: "Save whole screen shot to Trilium", + contexts: ["page"] + }, + { + id: "trilium-save-page", + title: "Save whole page to Trilium", + contexts: ["page"] + }, + { + id: "trilium-save-link", + title: "Save link to Trilium", + contexts: ["link"] + }, + { + id: "trilium-save-image", + title: "Save image to Trilium", + contexts: ["image"] + } +]; + +export default function setupContextMenu() { + // Context menu items need to be registered only once. + // https://stackoverflow.com/questions/64318529/cannot-create-item-with-duplicate-context-menu-id-in-extension + browser.runtime.onInstalled.addListener(() => { + for (const item of CONTEXT_MENU_ITEMS) { + browser.contextMenus.create(item); + } + }); +} diff --git a/apps/web-clipper/entrypoints/background/index.ts b/apps/web-clipper/entrypoints/background/index.ts index 8657ee5117..7d99abc997 100644 --- a/apps/web-clipper/entrypoints/background/index.ts +++ b/apps/web-clipper/entrypoints/background/index.ts @@ -1,5 +1,6 @@ import { randomString, Rect } from "@/utils"; +import setupContextMenu from "./context_menu"; import TriliumServerFacade from "./trilium_server_facade"; type BackgroundMessage = { @@ -40,6 +41,8 @@ export default defineBackground(() => { } }); + setupContextMenu(); + function cropImageManifestV2(newArea: Rect, dataUrl: string) { return new Promise((resolve, reject) => { const img = new Image(); @@ -115,42 +118,6 @@ export default defineBackground(() => { return await browser.tabs.captureVisibleTab({ format: 'png' }); } - browser.contextMenus.create({ - id: "trilium-save-selection", - title: "Save selection to Trilium", - contexts: ["selection"] - }); - - browser.contextMenus.create({ - id: "trilium-save-cropped-screenshot", - title: "Crop screen shot to Trilium", - contexts: ["page"] - }); - - browser.contextMenus.create({ - id: "trilium-save-whole-screenshot", - title: "Save whole screen shot to Trilium", - contexts: ["page"] - }); - - browser.contextMenus.create({ - id: "trilium-save-page", - title: "Save whole page to Trilium", - contexts: ["page"] - }); - - browser.contextMenus.create({ - id: "trilium-save-link", - title: "Save link to Trilium", - contexts: ["link"] - }); - - browser.contextMenus.create({ - id: "trilium-save-image", - title: "Save image to Trilium", - contexts: ["image"] - }); - async function getActiveTab() { const tabs = await browser.tabs.query({ active: true, From bbbdab42ca2666fbf8cab04f1d3f9378a6189fc3 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 26 Jan 2026 19:38:11 +0200 Subject: [PATCH 2/9] fix(web-clipper): cash not working in Chrome --- .../entrypoints/options/index.html | 1 - apps/web-clipper/entrypoints/options/index.ts | 2 + apps/web-clipper/entrypoints/popup/index.html | 1 - apps/web-clipper/entrypoints/popup/popup.ts | 10 ++-- apps/web-clipper/lib/cash.min.js | 40 ------------- apps/web-clipper/package.json | 3 + pnpm-lock.yaml | 57 +++++++++---------- 7 files changed, 38 insertions(+), 76 deletions(-) delete mode 100644 apps/web-clipper/lib/cash.min.js diff --git a/apps/web-clipper/entrypoints/options/index.html b/apps/web-clipper/entrypoints/options/index.html index 331a36a02e..abe09d4458 100644 --- a/apps/web-clipper/entrypoints/options/index.html +++ b/apps/web-clipper/entrypoints/options/index.html @@ -54,7 +54,6 @@

Note that the entered password is not stored anywhere, it will be only used to retrieve an authorization token from the server instance which will be then used to send the clipped notes.

- diff --git a/apps/web-clipper/entrypoints/options/index.ts b/apps/web-clipper/entrypoints/options/index.ts index c7cb3d4bdf..b4050c977b 100644 --- a/apps/web-clipper/entrypoints/options/index.ts +++ b/apps/web-clipper/entrypoints/options/index.ts @@ -1,3 +1,5 @@ +import $ from "cash-dom"; + const $triliumServerUrl = $("#trilium-server-url"); const $triliumServerPassword = $("#trilium-server-password"); diff --git a/apps/web-clipper/entrypoints/popup/index.html b/apps/web-clipper/entrypoints/popup/index.html index cdf2241cff..a655a5e4a8 100644 --- a/apps/web-clipper/entrypoints/popup/index.html +++ b/apps/web-clipper/entrypoints/popup/index.html @@ -46,7 +46,6 @@
Status: unknown
- diff --git a/apps/web-clipper/entrypoints/popup/popup.ts b/apps/web-clipper/entrypoints/popup/popup.ts index 0e4613b794..aa4f0bc2c1 100644 --- a/apps/web-clipper/entrypoints/popup/popup.ts +++ b/apps/web-clipper/entrypoints/popup/popup.ts @@ -1,3 +1,5 @@ +import $ from "cash-dom"; + import { createLink } from "@/utils"; async function sendMessage(message: object) { @@ -38,7 +40,7 @@ $saveTabsButton.on("click", () => sendMessage({name: 'save-tabs'})); const $saveLinkWithNoteWrapper = $("#save-link-with-note-wrapper"); const $textNote = $("#save-link-with-note-textarea"); -const $keepTitle = $("#keep-title-checkbox"); +const $keepTitle = $("#keep-title-checkbox"); $textNote.on('keypress', (event) => { if ((event.which === 10 || event.which === 13) && event.ctrlKey) { @@ -52,7 +54,7 @@ $textNote.on('keypress', (event) => { $("#save-link-with-note-button").on("click", () => { $saveLinkWithNoteWrapper.show(); - $textNote[0].focus(); + $textNote[0]?.focus(); }); $("#cancel-button").on("click", () => { @@ -70,7 +72,7 @@ async function saveLinkWithNote() { title = ''; content = ''; } - else if ($keepTitle[0].checked){ + else if (($keepTitle[0] as HTMLInputElement | undefined)?.checked){ title = ''; content = textNoteVal; } @@ -162,7 +164,7 @@ browser.runtime.onMessage.addListener(request => { const a = createLink({name: 'openNoteInTrilium', noteId: searchNote.noteId}, "Open in Trilium."); $alreadyVisited.text(`Already visited website!`); - $alreadyVisited[0].appendChild(a); + $alreadyVisited[0]?.appendChild(a); }else{ $alreadyVisited.html(''); } diff --git a/apps/web-clipper/lib/cash.min.js b/apps/web-clipper/lib/cash.min.js deleted file mode 100644 index 044700612a..0000000000 --- a/apps/web-clipper/lib/cash.min.js +++ /dev/null @@ -1,40 +0,0 @@ -/* MIT https://github.com/kenwheeler/cash */ -(function(){ -'use strict';var e={"class":"className",contenteditable:"contentEditable","for":"htmlFor",readonly:"readOnly",maxlength:"maxLength",tabindex:"tabIndex",colspan:"colSpan",rowspan:"rowSpan",usemap:"useMap"};function g(a,b){try{return a(b)}catch(c){return b}} -var m=document,n=window,p=m.documentElement,r=m.createElement.bind(m),aa=r("div"),t=r("table"),ba=r("tbody"),ca=r("tr"),u=Array.isArray,v=Array.prototype,da=v.concat,w=v.filter,ea=v.indexOf,fa=v.map,ha=v.push,ia=v.slice,x=v.some,ja=v.splice,ka=/^#[\w-]*$/,la=/^\.[\w-]*$/,ma=/<.+>/,na=/^\w+$/;function y(a,b){return a&&(A(b)||B(b))?la.test(a)?b.getElementsByClassName(a.slice(1)):na.test(a)?b.getElementsByTagName(a):b.querySelectorAll(a):[]} -var C=function(){function a(a,c){if(a){if(a instanceof C)return a;var b=a;if(D(a)){if(b=(c instanceof C?c[0]:c)||m,b=ka.test(a)?b.getElementById(a.slice(1)):ma.test(a)?oa(a):y(a,b),!b)return}else if(E(a))return this.ready(a);if(b.nodeType||b===n)b=[b];this.length=b.length;a=0;for(c=this.length;aarguments.length?this[0]&&this[0][a]:this.each(function(c,h){h[a]=b});for(var c in a)this.prop(c,a[c]);return this}};F.get=function(a){if(void 0===a)return ia.call(this);a=Number(a);return this[0>a?a+this.length:a]};F.eq=function(a){return G(this.get(a))}; -F.first=function(){return this.eq(0)};F.last=function(){return this.eq(-1)};function L(a){return D(a)?function(b,c){return qa(c,a)}:E(a)?a:a instanceof C?function(b,c){return a.is(c)}:a?function(b,c){return c===a}:function(){return!1}}F.filter=function(a){var b=L(a);return G(w.call(this,function(a,d){return b.call(a,d,a)}))};function M(a,b){return b?a.filter(b):a}var sa=/\S+/g;function N(a){return D(a)?a.match(sa)||[]:[]}F.hasClass=function(a){return!!a&&x.call(this,function(b){return B(b)&&b.classList.contains(a)})}; -F.removeAttr=function(a){var b=N(a);return this.each(function(a,d){B(d)&&I(b,function(a,b){d.removeAttribute(b)})})};F.attr=function(a,b){if(a){if(D(a)){if(2>arguments.length){if(!this[0]||!B(this[0]))return;var c=this[0].getAttribute(a);return null===c?void 0:c}return void 0===b?this:null===b?this.removeAttr(a):this.each(function(c,h){B(h)&&h.setAttribute(a,b)})}for(c in a)this.attr(c,a[c]);return this}}; -F.toggleClass=function(a,b){var c=N(a),d=void 0!==b;return this.each(function(a,f){B(f)&&I(c,function(a,c){d?b?f.classList.add(c):f.classList.remove(c):f.classList.toggle(c)})})};F.addClass=function(a){return this.toggleClass(a,!0)};F.removeClass=function(a){return arguments.length?this.toggleClass(a,!1):this.attr("class","")}; -function O(a,b,c,d){for(var h=[],f=E(b),k=d&&L(d),q=0,R=a.length;qarguments.length)return this[0]&&Q(this[0],a,c);if(!a)return this;b=xa(a,b,c);return this.each(function(d,f){B(f)&&(c?f.style.setProperty(a,b):f.style[a]=b)})}for(var d in a)this.css(d,a[d]);return this};var ya=/^\s+|\s+$/;function za(a,b){a=a.dataset[b]||a.dataset[H(b)];return ya.test(a)?a:g(JSON.parse,a)} -F.data=function(a,b){if(!a){if(!this[0])return;var c={},d;for(d in this[0].dataset)c[d]=za(this[0],d);return c}if(D(a))return 2>arguments.length?this[0]&&za(this[0],a):void 0===b?this:this.each(function(c,d){c=b;c=g(JSON.stringify,c);d.dataset[H(a)]=c});for(d in a)this.data(d,a[d]);return this};function Aa(a,b){var c=a.documentElement;return Math.max(a.body["scroll"+b],c["scroll"+b],a.body["offset"+b],c["offset"+b],c["client"+b])} -function Ba(a,b){return S(a,"border"+(b?"Left":"Top")+"Width")+S(a,"padding"+(b?"Left":"Top"))+S(a,"padding"+(b?"Right":"Bottom"))+S(a,"border"+(b?"Right":"Bottom")+"Width")} -I([!0,!1],function(a,b){I(["Width","Height"],function(a,d){F[(b?"outer":"inner")+d]=function(c){if(this[0])return K(this[0])?b?this[0]["inner"+d]:this[0].document.documentElement["client"+d]:A(this[0])?Aa(this[0],d):this[0][(b?"offset":"client")+d]+(c&&b?S(this[0],"margin"+(a?"Top":"Left"))+S(this[0],"margin"+(a?"Bottom":"Right")):0)}})}); -I(["Width","Height"],function(a,b){var c=b.toLowerCase();F[c]=function(d){if(!this[0])return void 0===d?void 0:this;if(!arguments.length)return K(this[0])?this[0].document.documentElement["client"+b]:A(this[0])?Aa(this[0],b):this[0].getBoundingClientRect()[c]-Ba(this[0],!a);var h=parseInt(d,10);return this.each(function(b,d){B(d)&&(b=Q(d,"boxSizing"),d.style[c]=xa(c,h+("border-box"===b?Ba(d,!a):0)))})}});var V={}; -F.toggle=function(a){return this.each(function(b,c){if(B(c))if(void 0===a?"none"===Q(c,"display"):a){if(c.style.display=c.___cd||"","none"===Q(c,"display")){b=c.style;c=c.tagName;if(V[c])c=V[c];else{var d=r(c);m.body.insertBefore(d,null);var h=Q(d,"display");m.body.removeChild(d);c=V[c]="none"!==h?h:"block"}b.display=c}}else c.___cd=Q(c,"display"),c.style.display="none"})};F.hide=function(){return this.toggle(!1)};F.show=function(){return this.toggle(!0)}; -function Ca(a,b){return!b||!x.call(b,function(b){return 0>a.indexOf(b)})}var W={focus:"focusin",blur:"focusout"},Da={mouseenter:"mouseover",mouseleave:"mouseout"},Ea=/^(mouse|pointer|contextmenu|drag|drop|click|dblclick)/i;function Fa(a,b,c,d,h){var f=a.___ce=a.___ce||{};f[b]=f[b]||[];f[b].push([c,d,h]);a.addEventListener(b,h)}function X(a){a=a.split(".");return[a[0],a.slice(1).sort()]} -function Y(a,b,c,d,h){var f=a.___ce=a.___ce||{};if(b)f[b]&&(f[b]=f[b].filter(function(f){var k=f[0],R=f[1];f=f[2];if(h&&f.guid!==h.guid||!Ca(k,c)||d&&d!==R)return!0;a.removeEventListener(b,f)}));else for(b in f)Y(a,b,c,d,h)} -F.off=function(a,b,c){var d=this;if(void 0===a)this.each(function(a,b){(B(b)||A(b)||K(b))&&Y(b)});else if(D(a))E(b)&&(c=b,b=""),I(N(a),function(a,h){a=X(Da[h]||W[h]||h);var f=a[0],k=a[1];d.each(function(a,d){(B(d)||A(d)||K(d))&&Y(d,f,k,b,c)})});else for(var h in a)this.off(h,a[h]);return this}; -F.on=function(a,b,c,d,h){var f=this;if(!D(a)){for(var k in a)this.on(k,b,c,a[k],h);return this}D(b)||(void 0!==b&&null!==b&&(void 0!==c&&(d=c),c=b),b="");E(d)||(d=c,c=void 0);if(!d)return this;I(N(a),function(a,k){a=X(Da[k]||W[k]||k);var l=a[0],q=a[1];l&&f.each(function(a,f){if(B(f)||A(f)||K(f))a=function Ja(a){if(!a.namespace||Ca(q,a.namespace.split("."))){var k=f;if(b){for(var z=a.target;!qa(z,b);){if(z===f)return;z=z.parentNode;if(!z)return}k=z;a.___cd=!0}a.___cd&&Object.defineProperty(a,"currentTarget", -{configurable:!0,get:function(){return k}});Object.defineProperty(a,"data",{configurable:!0,get:function(){return c}});z=d.call(k,a,a.___td);h&&Y(f,l,q,b,Ja);!1===z&&(a.preventDefault(),a.stopPropagation())}},a.guid=d.guid=d.guid||G.guid++,Fa(f,l,q,b,a)})});return this};F.one=function(a,b,c,d){return this.on(a,b,c,d,!0)};F.ready=function(a){function b(){return setTimeout(a,0,G)}"loading"!==m.readyState?b():m.addEventListener("DOMContentLoaded",b);return this}; -F.trigger=function(a,b){if(D(a)){var c=X(a),d=c[0];c=c[1];if(!d)return this;var h=Ea.test(d)?"MouseEvents":"HTMLEvents";a=m.createEvent(h);a.initEvent(d,!0,!0);a.namespace=c.join(".")}a.___td=b;var f=a.type in W;return this.each(function(b,c){if(f&&E(c[a.type]))c[a.type]();else c.dispatchEvent(a)})};function Ga(a){return a.multiple&&a.options?O(w.call(a.options,function(a){return a.selected&&!a.disabled&&!a.parentNode.disabled}),"value"):a.value||""} -var Ha=/%20/g,Ia=/\r?\n/g,Ka=/file|reset|submit|button|image/i,La=/radio|checkbox/i;F.serialize=function(){var a="";this.each(function(b,c){I(c.elements||[c],function(b,c){c.disabled||!c.name||"FIELDSET"===c.tagName||Ka.test(c.type)||La.test(c.type)&&!c.checked||(b=Ga(c),void 0!==b&&(b=u(b)?b:[b],I(b,function(b,d){b=a;d="&"+encodeURIComponent(c.name)+"="+encodeURIComponent(d.replace(Ia,"\r\n")).replace(Ha,"+");a=b+d})))})});return a.slice(1)}; -F.val=function(a){return arguments.length?this.each(function(b,c){if((b=c.multiple&&c.options)||La.test(c.type)){var d=u(a)?fa.call(a,String):null===a?[]:[String(a)];b?I(c.options,function(a,b){b.selected=0<=d.indexOf(b.value)},!0):c.checked=0<=d.indexOf(c.value)}else c.value=void 0===a||null===a?"":a}):this[0]&&Ga(this[0])};F.clone=function(){return this.map(function(a,b){return b.cloneNode(!0)})};F.detach=function(a){M(this,a).each(function(a,c){c.parentNode&&c.parentNode.removeChild(c)});return this}; -var Ma=/^\s*<(\w+)[^>]*>/,Na=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,Oa={"*":aa,tr:ba,td:ca,th:ca,thead:t,tbody:t,tfoot:t};function oa(a){if(!D(a))return[];if(Na.test(a))return[r(RegExp.$1)];var b=Ma.test(a)&&RegExp.$1;b=Oa[b]||Oa["*"];b.innerHTML=a;return G(b.childNodes).detach().get()}G.parseHTML=oa;F.empty=function(){return this.each(function(a,b){for(;b.firstChild;)b.removeChild(b.firstChild)})}; -F.html=function(a){return arguments.length?void 0===a?this:this.each(function(b,c){B(c)&&(c.innerHTML=a)}):this[0]&&this[0].innerHTML};F.remove=function(a){M(this,a).detach().off();return this};F.text=function(a){return void 0===a?this[0]?this[0].textContent:"":this.each(function(b,c){B(c)&&(c.textContent=a)})};F.unwrap=function(){this.parent().each(function(a,b){"BODY"!==b.tagName&&(a=G(b),a.replaceWith(a.children()))});return this}; -F.offset=function(){var a=this[0];if(a)return a=a.getBoundingClientRect(),{top:a.top+n.pageYOffset,left:a.left+n.pageXOffset}};F.offsetParent=function(){return this.map(function(a,b){for(a=b.offsetParent;a&&"static"===Q(a,"position");)a=a.offsetParent;return a||p})}; -F.position=function(){var a=this[0];if(a){var b="fixed"===Q(a,"position"),c=b?a.getBoundingClientRect():this.offset();if(!b){var d=a.ownerDocument;for(b=a.offsetParent||d.documentElement;(b===d.body||b===d.documentElement)&&"static"===Q(b,"position");)b=b.parentNode;b!==a&&B(b)&&(d=G(b).offset(),c.top-=d.top+S(b,"borderTopWidth"),c.left-=d.left+S(b,"borderLeftWidth"))}return{top:c.top-S(a,"marginTop"),left:c.left-S(a,"marginLeft")}}}; -F.children=function(a){return M(G(P(O(this,function(a){return a.children}))),a)};F.contents=function(){return G(P(O(this,function(a){return"IFRAME"===a.tagName?[a.contentDocument]:"TEMPLATE"===a.tagName?a.content.childNodes:a.childNodes})))};F.find=function(a){return G(P(O(this,function(b){return y(a,b)})))};var Pa=/^\s*\s*$/g,Qa=/^$|^module$|\/(java|ecma)script/i,Ra=["type","src","nonce","noModule"]; -function Sa(a,b){a=G(a);a.filter("script").add(a.find("script")).each(function(a,d){if(Qa.test(d.type)&&p.contains(d)){var c=r("script");c.text=d.textContent.replace(Pa,"");I(Ra,function(a,b){d[b]&&(c[b]=d[b])});b.head.insertBefore(c,null);b.head.removeChild(c)}})} -function Z(a,b,c,d,h,f,k,q){I(a,function(a,f){I(G(f),function(a,f){I(G(b),function(b,k){var l=c?k:f;b=c?a:b;k=c?f:k;l=b?l.cloneNode(!0):l;b=!b;h?k.insertBefore(l,d?k.firstChild:null):k.parentNode.insertBefore(l,d?k:k.nextSibling);b&&Sa(l,k.ownerDocument)},q)},k)},f);return b}F.after=function(){return Z(arguments,this,!1,!1,!1,!0,!0)};F.append=function(){return Z(arguments,this,!1,!1,!0)};F.appendTo=function(a){return Z(arguments,this,!0,!1,!0)};F.before=function(){return Z(arguments,this,!1,!0)}; -F.insertAfter=function(a){return Z(arguments,this,!0,!1,!1,!1,!1,!0)};F.insertBefore=function(a){return Z(arguments,this,!0,!0)};F.prepend=function(){return Z(arguments,this,!1,!0,!0,!0,!0)};F.prependTo=function(a){return Z(arguments,this,!0,!0,!0,!1,!1,!0)};F.replaceWith=function(a){return this.before(a).remove()};F.replaceAll=function(a){G(a).replaceWith(this);return this};F.wrapAll=function(a){a=G(a);for(var b=a[0];b.children.length;)b=b.firstElementChild;this.first().before(a);return this.appendTo(b)}; -F.wrap=function(a){return this.each(function(b,c){var d=G(a)[0];G(c).wrapAll(b?d.cloneNode(!0):d)})};F.wrapInner=function(a){return this.each(function(b,c){b=G(c);c=b.contents();c.length?c.wrapAll(a):b.append(a)})};F.has=function(a){var b=D(a)?function(b,d){return y(a,d).length}:function(b,d){return d.contains(a)};return this.filter(b)};F.is=function(a){var b=L(a);return x.call(this,function(a,d){return b.call(a,d,a)})};F.next=function(a,b,c){return M(G(P(O(this,"nextElementSibling",b,c))),a)}; -F.nextAll=function(a){return this.next(a,!0)};F.nextUntil=function(a,b){return this.next(b,!0,a)};F.not=function(a){var b=L(a);return this.filter(function(c,d){return(!D(a)||B(d))&&!b.call(d,c,d)})};F.parent=function(a){return M(G(P(O(this,"parentNode"))),a)};F.index=function(a){var b=a?G(a)[0]:this[0];a=a?this:G(b).parent().children();return ea.call(a,b)};F.closest=function(a){var b=this.filter(a);if(b.length)return b;var c=this.parent();return c.length?c.closest(a):b}; -F.parents=function(a,b){return M(G(P(O(this,"parentElement",!0,b))),a)};F.parentsUntil=function(a,b){return this.parents(b,a)};F.prev=function(a,b,c){return M(G(P(O(this,"previousElementSibling",b,c))),a)};F.prevAll=function(a){return this.prev(a,!0)};F.prevUntil=function(a,b){return this.prev(b,!0,a)};F.siblings=function(a){return M(G(P(O(this,function(a){return G(a).parent().children().not(a)}))),a)};"undefined"!==typeof exports?module.exports=G:n.cash=n.$=G; -})(); \ No newline at end of file diff --git a/apps/web-clipper/package.json b/apps/web-clipper/package.json index 2853dcb900..97aa421df1 100644 --- a/apps/web-clipper/package.json +++ b/apps/web-clipper/package.json @@ -17,5 +17,8 @@ "devDependencies": { "@wxt-dev/auto-icons": "1.1.0", "wxt": "0.20.13" + }, + "dependencies": { + "cash-dom": "8.1.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a0450f01a..c716b4dd18 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -818,6 +818,10 @@ importers: version: 17.2.3 apps/web-clipper: + dependencies: + cash-dom: + specifier: 8.1.5 + version: 8.1.5 devDependencies: '@wxt-dev/auto-icons': specifier: 1.1.0 @@ -6871,6 +6875,9 @@ packages: canvas-roundrect-polyfill@0.0.1: resolution: {integrity: sha512-yWq+R3U3jE+coOeEb3a3GgE2j/0MMiDKM/QpLb6h9ihf5fGY9UXtvK9o4vNqjWXoZz7/3EaSVU3IX53TvFFUOw==} + cash-dom@8.1.5: + resolution: {integrity: sha512-/BS05CfzyHR5xT2ksKj1sDLPaOv5rSmIwoGxNgdKwUtnIuiJ5neMxVEmZxvfyJiSjGbOMD0Lwe+9v+fszDqHew==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -15829,6 +15836,8 @@ snapshots: '@ckeditor/ckeditor5-core': 47.4.0 '@ckeditor/ckeditor5-upload': 47.4.0 ckeditor5: 47.4.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-ai@47.4.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: @@ -15969,12 +15978,16 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 '@ckeditor/ckeditor5-widget': 47.4.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-cloud-services@47.4.0': dependencies: '@ckeditor/ckeditor5-core': 47.4.0 '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-code-block@47.4.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)': dependencies: @@ -16167,6 +16180,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-editor-classic@47.4.0': dependencies: @@ -16176,6 +16191,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-editor-decoupled@47.4.0': dependencies: @@ -16185,6 +16202,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-editor-inline@47.4.0': dependencies: @@ -16194,6 +16213,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-editor-multi-root@47.4.0': dependencies: @@ -16216,8 +16237,6 @@ snapshots: '@ckeditor/ckeditor5-table': 47.4.0 '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-emoji@47.4.0': dependencies: @@ -16274,8 +16293,6 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.4.0 '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-export-word@47.4.0': dependencies: @@ -16300,6 +16317,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-font@47.4.0': dependencies: @@ -16374,6 +16393,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 '@ckeditor/ckeditor5-widget': 47.4.0 ckeditor5: 47.4.0 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-html-embed@47.4.0': dependencies: @@ -16419,8 +16440,6 @@ snapshots: '@ckeditor/ckeditor5-widget': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-import-word@47.4.0': dependencies: @@ -16433,8 +16452,6 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.4.0 '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-indent@47.4.0': dependencies: @@ -16508,8 +16525,6 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.4.0 '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-markdown-gfm@47.4.0': dependencies: @@ -16558,8 +16573,6 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-merge-fields@47.4.0': dependencies: @@ -16572,8 +16585,6 @@ snapshots: '@ckeditor/ckeditor5-widget': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-minimap@47.4.0': dependencies: @@ -16582,8 +16593,6 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.4.0 '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-operations-compressor@47.4.0': dependencies: @@ -16638,8 +16647,6 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 '@ckeditor/ckeditor5-widget': 47.4.0 ckeditor5: 47.4.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-pagination@47.4.0': dependencies: @@ -16747,8 +16754,6 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.4.0 '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-slash-command@47.4.0': dependencies: @@ -16761,8 +16766,6 @@ snapshots: '@ckeditor/ckeditor5-ui': 47.4.0 '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-source-editing-enhanced@47.4.0': dependencies: @@ -16810,8 +16813,6 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-table@47.4.0': dependencies: @@ -16824,8 +16825,6 @@ snapshots: '@ckeditor/ckeditor5-widget': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-template@47.4.0': dependencies: @@ -16936,8 +16935,6 @@ snapshots: '@ckeditor/ckeditor5-engine': 47.4.0 '@ckeditor/ckeditor5-utils': 47.4.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-widget@47.4.0': dependencies: @@ -16957,8 +16954,6 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.4.0 ckeditor5: 47.4.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@codemirror/autocomplete@6.18.6': dependencies: @@ -22579,6 +22574,8 @@ snapshots: canvas-roundrect-polyfill@0.0.1: {} + cash-dom@8.1.5: {} + ccount@2.0.1: {} chai@6.2.1: {} From ab519a4caa007b895549249ae6761dd78f63ff71 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 26 Jan 2026 20:06:57 +0200 Subject: [PATCH 3/9] chore(web-clipper): rephrase "already visited" & fix spacing --- apps/web-clipper/entrypoints/popup/popup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web-clipper/entrypoints/popup/popup.ts b/apps/web-clipper/entrypoints/popup/popup.ts index aa4f0bc2c1..c68e7e6af9 100644 --- a/apps/web-clipper/entrypoints/popup/popup.ts +++ b/apps/web-clipper/entrypoints/popup/popup.ts @@ -163,7 +163,7 @@ browser.runtime.onMessage.addListener(request => { if (searchNote.status === 'found'){ const a = createLink({name: 'openNoteInTrilium', noteId: searchNote.noteId}, "Open in Trilium."); - $alreadyVisited.text(`Already visited website!`); + $alreadyVisited.text(`Web page already clipped. `); $alreadyVisited[0]?.appendChild(a); }else{ $alreadyVisited.html(''); From c97c69900be9cb56919e94c082762e9aedca2e38 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 26 Jan 2026 20:10:18 +0200 Subject: [PATCH 4/9] chore(web-clipper): minor typo in "screenshot" --- apps/web-clipper/entrypoints/background/context_menu.ts | 4 ++-- apps/web-clipper/entrypoints/popup/index.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/web-clipper/entrypoints/background/context_menu.ts b/apps/web-clipper/entrypoints/background/context_menu.ts index 6685651fbd..28786df7bf 100644 --- a/apps/web-clipper/entrypoints/background/context_menu.ts +++ b/apps/web-clipper/entrypoints/background/context_menu.ts @@ -6,12 +6,12 @@ const CONTEXT_MENU_ITEMS: Browser.contextMenus.CreateProperties[] = [ }, { id: "trilium-save-cropped-screenshot", - title: "Crop screen shot to Trilium", + title: "Crop screenshot to Trilium", contexts: ["page"] }, { id: "trilium-save-whole-screenshot", - title: "Save whole screen shot to Trilium", + title: "Save whole screenshot to Trilium", contexts: ["page"] }, { diff --git a/apps/web-clipper/entrypoints/popup/index.html b/apps/web-clipper/entrypoints/popup/index.html index a655a5e4a8..207d6433cb 100644 --- a/apps/web-clipper/entrypoints/popup/index.html +++ b/apps/web-clipper/entrypoints/popup/index.html @@ -20,8 +20,8 @@
- - + + From 537d92421c6ebd05805e976221bd06495b214923 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 26 Jan 2026 20:20:46 +0200 Subject: [PATCH 5/9] chore(web-clipper): fix warning related to permissions --- apps/web-clipper/wxt.config.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/web-clipper/wxt.config.ts b/apps/web-clipper/wxt.config.ts index 1ca4460a1e..7dd1c0a3a9 100644 --- a/apps/web-clipper/wxt.config.ts +++ b/apps/web-clipper/wxt.config.ts @@ -12,13 +12,15 @@ export default defineConfig({ permissions: [ "activeTab", "tabs", - "http://*/", - "https://*/", - "", "storage", "contextMenus", manifestVersion === 3 && "offscreen" ].filter(Boolean), + host_permissions: [ + "http://*/", + "https://*/", + "", + ], browser_specific_settings: { gecko: { // See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings#id. From 82ea4c1a04ea3346705bb4d0f6c8d381d3d07dbe Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 26 Jan 2026 20:37:32 +0200 Subject: [PATCH 6/9] docs(guide): add instructions on installing from .zip --- .../Installation & Setup/Web Clipper.html | 78 +++++++++++++++++-- .../Developer Guide/Documentation.md | 2 +- .../Installation & Setup/Web Clipper.md | 30 +++++++ 3 files changed, 102 insertions(+), 8 deletions(-) diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Web Clipper.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Web Clipper.html index effb6e395b..77eb7dea73 100644 --- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Web Clipper.html +++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Installation & Setup/Web Clipper.html @@ -7,13 +7,9 @@

Supported browsers

Trilium Web Clipper officially supports the following web browsers:

    -
  • -

    Mozilla Firefox, using Manifest v2.

    -
  • -
  • -

    Google Chrome, using Manifest v3. Theoretically the extension should work - on other Chromium-based browsers as well, but they are not officially supported.

    -
  • +
  • Mozilla Firefox, using Manifest v2.
  • +
  • Google Chrome, using Manifest v3. Theoretically the extension should work + on other Chromium-based browsers as well, but they are not officially supported.

Obtaining the extension