Merge branch 'develop' into feature/windows_signing_v3

This commit is contained in:
Elian Doran
2025-03-25 10:40:48 +02:00
committed by GitHub
15 changed files with 174 additions and 185 deletions

View File

@@ -55,4 +55,8 @@ describe("Linter", () => {
expect(await lint(`module.exports("Hi");`, "application/javascript;env=backend")).toStrictEqual([]);
expect(await lint(`module.exports("Hi");`, "application/javascript;env=frontend")).toStrictEqual([]);
});
it("ignores TypeScript file", async () => {
expect(await lint("export async function lint(code: string, mimeType: string) {}", "text/typescript-jsx")).toStrictEqual([]);
});
});

View File

@@ -10,6 +10,12 @@ export async function lint(code: string, mimeType: string) {
module: "readonly"
};
// Unsupported languages
if (mimeType.startsWith("text/typescript")) {
return [];
}
// Custom globals
if (mimeType === "application/javascript;env=frontend") {
globals = { ...globals, ...globalDefinitions.jquery };
} else if (mimeType === "application/javascript;env=backend") {

View File

@@ -206,7 +206,8 @@ export class TypedBasicWidget<T extends TypedComponent<any>> extends TypedCompon
doRender() {}
toggleInt(show: boolean | null | undefined) {
this.$widget.toggleClass("hidden-int", !show);
this.$widget.toggleClass("hidden-int", !show)
.toggleClass("visible", !!show);
}
isHiddenInt() {
@@ -214,7 +215,8 @@ export class TypedBasicWidget<T extends TypedComponent<any>> extends TypedCompon
}
toggleExt(show: boolean) {
this.$widget.toggleClass("hidden-ext", !show);
this.$widget.toggleClass("hidden-ext", !show)
.toggleClass("visible", !!show);
}
isHiddenExt() {

View File

@@ -13,7 +13,7 @@ export default class ShowTocWidgetButton extends OnClickButtonWidget {
constructor() {
super();
this.icon("bx-spreadsheet bx-rotate-180")
this.icon("bx-tn-toc")
.title(t("show_toc_widget_button.show_toc"))
.titlePlacement("bottom")
.onClick(() => {

View File

@@ -3,6 +3,14 @@ import { t } from "../../services/i18n.js";
import type FNote from "../../entities/fnote.js";
import type BasicWidget from "../basic_widget.js";
/*
* Note:
*
* For floating button widgets that require content to overflow, the has-overflow CSS class should
* be applied to the root element of the widget. Additionally, this root element may need to
* properly handle rounded corners, as defined by the --border-radius CSS variable.
*/
const TPL = `
<div class="floating-buttons no-print">
<style>
@@ -39,10 +47,18 @@ const TPL = `
top: 70px;
}
.type-canvas .floating-buttons-children > * {
--border-radius: 0; /* Overridden by themes */
}
.floating-buttons-children > *:not(.hidden-int):not(.no-content-hidden) {
margin: 2px;
}
.floating-buttons-children > *:not(.has-overflow) {
overflow: hidden;
}
.floating-buttons-children > button, .floating-buttons-children .floating-button {
font-size: 150%;
padding: 5px 10px 4px 10px;

View File

@@ -10,7 +10,7 @@ import froca from "../../services/froca.js";
import type FNote from "../../entities/fnote.js";
const TPL = `
<div class="backlinks-widget">
<div class="backlinks-widget has-overflow">
<style>
.backlinks-widget {
position: relative;
@@ -61,7 +61,7 @@ const TPL = `
<span class="backlinks-count"></span>
</div>
<div class="backlinks-items" style="display: none;"></div>
<div class="backlinks-items dropdown-menu" style="display: none;"></div>
</div>
`;
@@ -121,7 +121,8 @@ export default class BacklinksWidget extends NoteContextAwareWidget {
}
toggle(show: boolean) {
this.$widget.toggleClass("hidden-no-content", !show);
this.$widget.toggleClass("hidden-no-content", !show)
.toggleClass("visible", !!show);
}
clearItems() {

View File

@@ -5,6 +5,7 @@ import server from "../services/server.js";
import type FNote from "../entities/fnote.js";
import type { EventData } from "../components/app_context.js";
import type { Icon } from "./icon_list.js";
import { Dropdown } from "bootstrap";
const TPL = `
<div class="note-icon-widget dropdown">
@@ -88,6 +89,7 @@ interface IconToCountCache {
export default class NoteIconWidget extends NoteContextAwareWidget {
private dropdown!: bootstrap.Dropdown;
private $icon!: JQuery<HTMLElement>;
private $iconList!: JQuery<HTMLElement>;
private $iconCategory!: JQuery<HTMLElement>;
@@ -96,6 +98,8 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
doRender() {
this.$widget = $(TPL);
this.dropdown = Dropdown.getOrCreateInstance(this.$widget.find("[data-bs-toggle='dropdown']")[0]);
this.$icon = this.$widget.find("button.note-icon");
this.$iconList = this.$widget.find(".icon-list");
this.$iconList.on("click", "span", async (e) => {
@@ -130,6 +134,8 @@ export default class NoteIconWidget extends NoteContextAwareWidget {
async refreshWithNote(note: FNote) {
this.$icon.removeClass().addClass(`${note.getIcon()} note-icon`);
this.$icon.prop("disabled", !!(this.noteContext?.viewScope?.viewMode !== "default"));
this.dropdown.hide();
}
async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {

View File

@@ -579,11 +579,7 @@ table.promoted-attributes-in-tooltip th {
.tooltip {
font-size: var(--main-font-size) !important;
/*
TODO: Investigate the purpose of this
z-index: calc(var(--ck-z-panel) - 1) !important;
*/
z-index: 3000;
z-index: calc(var(--ck-z-panel) - 1) !important;
}
.tooltip-trigger {
@@ -1796,4 +1792,11 @@ footer.file-footer button {
.content-floating-buttons button.bx {
font-size: 130%;
padding: 1px 10px 1px 10px;
}
/* Customized icons */
.bx-tn-toc::before {
content: "\ec24";
transform: rotate(180deg);
}

View File

@@ -1305,7 +1305,7 @@ div.promoted-attribute-cell .multiplicity:has(span) {
/* Floating buttons container */
div#center-pane .floating-buttons-children {
opacity: 1;
overflow: hidden;
min-height: var(--floating-button-height);
transform-origin: right;
box-shadow: 1px 1px 1px var(--floating-button-shadow-color);
background: var(--floating-button-background-color);
@@ -1325,6 +1325,10 @@ div#center-pane .floating-buttons-children {
/* Floating buttons */
.floating-buttons-children {
--border-radius-size: 6px;
}
.floating-buttons-children > * {
margin: 0 !important;
}
@@ -1352,6 +1356,12 @@ div.floating-buttons-children .floating-button:active {
font-size: calc(var(--floating-button-icon-size) * 0.85);
}
/* The first visible floating button */
div.floating-buttons-children > *:nth-child(1 of .visible) {
--border-radius: var(--border-radius-size) 0 0 var(--border-radius-size);
border-radius: var(--border-radius);
}
/* "Show / hide floating buttons" buttons */
@keyframes floating-buttons-show-hide-button-animation {
@@ -1409,8 +1419,9 @@ div.floating-buttons-children:not(.temporarily-hidden) .close-floating-buttons-b
animation: floating-buttons-show-hide-button-animation 400ms ease-out;
}
div.floating-buttons-children .close-floating-buttons-button {
border-radius: 0;
div.floating-buttons-children .close-floating-buttons {
border-radius: 0 var(--border-radius-size) var(--border-radius-size) 0;
overflow: hidden;
}
div.floating-buttons-children .close-floating-buttons {
@@ -1426,18 +1437,27 @@ div.floating-buttons-children .close-floating-buttons:has(.close-floating-button
/* Backlink count */
.floating-buttons .backlinks-ticker {
.backlinks-widget .backlinks-ticker {
height: 100%;
padding: 0 10px;
border-radius: 0;
border-radius: var(--border-radius);
background: transparent;
user-select: none;
}
.floating-buttons .backlinks-ticker:has(.backlinks-count:hover) {
.backlinks-widget .backlinks-ticker:hover {
background: var(--floating-button-hover-background);
}
.backlinks-widget .backlinks-items {
--menu-padding-size: 20px;
}
/* TODO: Restyle the path */
.backlinks-widget .backlinks-items .note-path {
padding-inline-start: 8px;
}
/* Copy image reference */
.floating-buttons .copy-image-reference-button .hidden-image-copy {
@@ -1452,14 +1472,6 @@ div.floating-buttons-children .close-floating-buttons:has(.close-floating-button
gap: 0;
}
/* Individual icon position / size corrections */
/* Table of contents */
.floating-buttons .bx-spreadsheet::before {
/* Note: since the icon is rotated, a positive top margin will actually shift the icon upwards */
margin-top: .1em;
}
/* The highlight animation */
@keyframes floating-button-highlight {

View File

@@ -1,70 +0,0 @@
"use strict";
import path from "path";
import resourceDir from "./resource_dir.js";
import log from "./log.js";
import os from "os";
import fs from "fs";
import config from "./config.js";
import { isElectron } from "./utils.js";
const template = `[Desktop Entry]
Type=Application
Name=TriliumNext Notes
StartupWMClass=TriliumNext Notes
Icon=#APP_ROOT_DIR#/icon.png
Exec=#EXE_PATH#
Categories=Office
Terminal=false
`;
/**
* Installs .desktop icon into standard ~/.local/share/applications directory.
* We overwrite this file during every run as it might have been updated.
*/
function installLocalAppIcon() {
if (!isElectron || ["win32", "darwin"].includes(os.platform()) || (config.General && config.General.noDesktopIcon)) {
return;
}
if (!fs.existsSync(path.resolve(resourceDir.ELECTRON_APP_ROOT_DIR, "trilium-portable.sh"))) {
// simple heuristic to detect ".tar.xz" linux build (i.e., not flatpak, not debian)
// only in such case it's necessary to create an icon
return;
}
const desktopDir = path.resolve(os.homedir(), ".local/share/applications");
fs.stat(desktopDir, function (err, stats) {
if (err) {
// Directory doesn't exist, so we won't attempt to create the .desktop file
return;
}
if (stats.isDirectory()) {
const desktopFilePath = path.resolve(desktopDir, "trilium-notes.desktop");
fs.writeFile(desktopFilePath, getDesktopFileContent(), function (err) {
if (err) {
log.error("Desktop icon installation to ~/.local/share/applications failed.");
}
});
}
});
}
function getDesktopFileContent() {
return template.replace("#APP_ROOT_DIR#", escapePath(resourceDir.ELECTRON_APP_ROOT_DIR)).replace("#EXE_PATH#", escapePath(getExePath()));
}
function escapePath(path: string) {
return path.replace(/ /g, "\\ ");
}
function getExePath() {
return path.resolve(resourceDir.ELECTRON_APP_ROOT_DIR, "trilium");
}
export default {
installLocalAppIcon
};