2.14.1-beta-1, 0.18.0-26

This commit is contained in:
zsviczian
2025-07-28 21:48:44 +02:00
parent 351977f0d3
commit 41065ce9f9
11 changed files with 43 additions and 32 deletions

View File

@@ -1,7 +1,7 @@
{ {
"id": "obsidian-excalidraw-plugin", "id": "obsidian-excalidraw-plugin",
"name": "Excalidraw", "name": "Excalidraw",
"version": "2.14.0", "version": "2.14.1-beta-1",
"minAppVersion": "1.5.7", "minAppVersion": "1.5.7",
"description": "An Obsidian plugin to edit and view Excalidraw drawings", "description": "An Obsidian plugin to edit and view Excalidraw drawings",
"author": "Zsolt Viczian", "author": "Zsolt Viczian",

View File

@@ -23,7 +23,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@popperjs/core": "^2.11.8", "@popperjs/core": "^2.11.8",
"@zsviczian/excalidraw": "0.18.0-25", "@zsviczian/excalidraw": "0.18.0-26",
"chroma-js": "^3.1.2", "chroma-js": "^3.1.2",
"clsx": "^2.0.0", "clsx": "^2.0.0",
"@zsviczian/colormaster": "^1.2.2", "@zsviczian/colormaster": "^1.2.2",

View File

@@ -49,7 +49,7 @@ const jsxRuntimeShim = `
const mathjaxtosvg_pkg = isLib ? "" : fs.readFileSync("./MathjaxToSVG/dist/index.js", "utf8"); const mathjaxtosvg_pkg = isLib ? "" : fs.readFileSync("./MathjaxToSVG/dist/index.js", "utf8");
const LANGUAGES = ['ru', 'zh-cn', 'zh-tw']; //english is not compressed as it is always loaded by default const LANGUAGES = ['ru', 'zh-cn', 'zh-tw', 'es']; //english is not compressed as it is always loaded by default
function trimLastSemicolon(input) { function trimLastSemicolon(input) {
if (input.endsWith(";")) { if (input.endsWith(";")) {

View File

@@ -17,6 +17,15 @@ I build this plugin in my free time, as a labor of love. Curious about the philo
<div class="ex-coffee-div"><a href="https://ko-fi.com/zsolt"><img src="https://storage.ko-fi.com/cdn/kofi6.png?v=6" border="0" alt="Buy Me a Coffee at ko-fi.com" height=45></a></div> <div class="ex-coffee-div"><a href="https://ko-fi.com/zsolt"><img src="https://storage.ko-fi.com/cdn/kofi6.png?v=6" border="0" alt="Buy Me a Coffee at ko-fi.com" height=45></a></div>
`, `,
"2.14.1":`
## New
- Added Spanish translation by [@Joakim31](https://github.com/Joakim31) [#2425](https://github.com/zsviczian/obsidian-excalidraw-plugin/pull/2425)
- Incremental minor updates from the main Excalidraw project.
## Fixed
- Styling issues impacting native Obsidian search/replace dialogs. [#2420](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/2420)
- Now using native Obsidian attachment location function. 🙏 [mnaoumov](https://github.com/mnaoumov) [#2421](https://github.com/zsviczian/obsidian-excalidraw-plugin/pull/2421), potentially fixes [#179](https://github.com/RainCat1998/obsidian-custom-attachment-location/issues/179) of the Obsidian Custom Attachment Location plugin issue.
`,
"2.14.0":` "2.14.0":`
## A Big "Small" Update ## A Big "Small" Update
- Added search to Excalidraw Settings, plus added a link to access the public NotebookLM workbook pre-loaded with everything about the plugin - Added search to Excalidraw Settings, plus added a link to access the public NotebookLM workbook pre-loaded with everything about the plugin

View File

@@ -191,7 +191,7 @@ export class ScriptEngine {
...this.scriptIconMap, ...this.scriptIconMap,
}; };
const splitname = splitFolderAndFilename(name) const splitname = splitFolderAndFilename(name)
this.scriptIconMap[scriptPath] = { name:splitname.filename, group: splitname.folderpath === "/" ? "" : splitname.folderpath, svgString }; this.scriptIconMap[scriptPath] = { name:splitname.filename, group: splitname.folderpath, svgString };
this.updateToolPannels(); this.updateToolPannels();
} }

View File

@@ -28,7 +28,7 @@ export class ContentSearcher {
* Creates search UI elements styled like Obsidian's native search * Creates search UI elements styled like Obsidian's native search
*/ */
private createSearchElements(): void { private createSearchElements(): void {
this.searchBarWrapper = createDiv("document-search-container"); this.searchBarWrapper = createDiv("excalidraw-search document-search-container");
const documentSearch = createDiv("document-search"); const documentSearch = createDiv("document-search");
this.inputContainer = createDiv("search-input-container document-search-input"); this.inputContainer = createDiv("search-input-container document-search-input");
this.searchBar = createEl("input",{type: "text", placeholder: "Find..."}); this.searchBar = createEl("input",{type: "text", placeholder: "Find..."});

View File

@@ -2,7 +2,7 @@ import { ExcalidrawEmbeddableElement, ExcalidrawFrameElement, ExcalidrawImageEle
import { Mutable } from "@zsviczian/excalidraw/types/common/src/utility-types"; import { Mutable } from "@zsviczian/excalidraw/types/common/src/utility-types";
import { getEA } from "src/core"; import { getEA } from "src/core";
import { ExcalidrawAutomate } from "src/shared/ExcalidrawAutomate"; import { ExcalidrawAutomate } from "src/shared/ExcalidrawAutomate";
import { getCropFileNameAndFolder, getListOfTemplateFiles, splitFolderAndFilename } from "./fileUtils"; import { getCropFileNameAndFolder, getListOfTemplateFiles } from "./fileUtils";
import { Notice, TFile } from "obsidian"; import { Notice, TFile } from "obsidian";
import { Radians } from "@zsviczian/excalidraw/types/math/src/types"; import { Radians } from "@zsviczian/excalidraw/types/math/src/types";

View File

@@ -11,7 +11,7 @@ import ExcalidrawView from "src/view/ExcalidrawView";
/** /**
* Splits a full path including a folderpath and a filename into separate folderpath and filename components * Splits a full path including a folderpath and a filename into separate folderpath and filename components
* @param filepath * @param filepath
* @returns folderpath will be normalized. This means "/" for root folder and no trailing "/" for other folders * @returns returns "" for root folder and normalized path for subfolders (no trailing "/", e.g. "folder/subfolder")
*/ */
type ImageExtension = keyof typeof IMAGE_MIME_TYPES; type ImageExtension = keyof typeof IMAGE_MIME_TYPES;
@@ -23,11 +23,13 @@ export function splitFolderAndFilename(filepath: string): {
} { } {
const lastIndex = filepath.lastIndexOf("/"); const lastIndex = filepath.lastIndexOf("/");
const filename = lastIndex == -1 ? filepath : filepath.substring(lastIndex + 1); const filename = lastIndex == -1 ? filepath : filepath.substring(lastIndex + 1);
const lastDotIndex = filename.lastIndexOf(".");
const folderpath = filepath.substring(0, lastIndex);
return { return {
folderpath: normalizePath(filepath.substring(0, lastIndex)), folderpath: folderpath ? normalizePath(folderpath) : "",
filename, filename,
basename: filename.replace(/\.[^/.]+$/, ""), basename: filename.replace(/\.[^/.]+$/, ""),
extension: filename.substring(filename.lastIndexOf(".") + 1), extension: lastDotIndex > 0 ? filename.substring(lastDotIndex + 1) : "",
}; };
} }
@@ -540,7 +542,7 @@ export async function importFileToVault(app: App, fname: string, content: string
export async function createOrOverwriteFile(app: App, path: string, content: string | ArrayBuffer | Blob): Promise<TFile> { export async function createOrOverwriteFile(app: App, path: string, content: string | ArrayBuffer | Blob): Promise<TFile> {
const {folderpath} = splitFolderAndFilename(path); const {folderpath} = splitFolderAndFilename(path);
if(folderpath && folderpath !== "/") { if(folderpath) {
await checkAndCreateFolder(folderpath); await checkAndCreateFolder(folderpath);
} }
const file = app.vault.getAbstractFileByPath(normalizePath(path)); const file = app.vault.getAbstractFileByPath(normalizePath(path));

View File

@@ -3,10 +3,10 @@ import {
Editor, Editor,
FrontMatterCache, FrontMatterCache,
MarkdownView, MarkdownView,
normalizePath, OpenViewState, parseFrontMatterEntry, TFile, View, ViewState, Workspace, WorkspaceLeaf, WorkspaceSplit OpenViewState, parseFrontMatterEntry, TFile, View, ViewState, Workspace, WorkspaceLeaf, WorkspaceSplit
} from "obsidian"; } from "obsidian";
import ExcalidrawPlugin from "../core/main"; import ExcalidrawPlugin from "../core/main";
import { checkAndCreateFolder, splitFolderAndFilename } from "./fileUtils"; import { splitFolderAndFilename } from "./fileUtils";
import { linkClickModifierType, ModifierKeys } from "./modifierkeyHelper"; import { linkClickModifierType, ModifierKeys } from "./modifierkeyHelper";
import { DEVICE, EXCALIDRAW_PLUGIN, REG_BLOCK_REF_CLEAN, REG_SECTION_REF_CLEAN, VIEW_TYPE_EXCALIDRAW } from "src/constants/constants"; import { DEVICE, EXCALIDRAW_PLUGIN, REG_BLOCK_REF_CLEAN, REG_SECTION_REF_CLEAN, VIEW_TYPE_EXCALIDRAW } from "src/constants/constants";
import yaml from "js-yaml"; import yaml from "js-yaml";
@@ -174,16 +174,12 @@ export const getAttachmentsFolderAndFilePath = async (
activeViewFilePath: string, activeViewFilePath: string,
newFileName: string newFileName: string
): Promise<{ folder: string; filepath: string; }> => { ): Promise<{ folder: string; filepath: string; }> => {
const NOT_FOUND_INDEX = -1; const { basename, extension } = splitFolderAndFilename(newFileName);
const extensionSeparatorIndex = newFileName.lastIndexOf(".");
const attachmentFileBasename = extensionSeparatorIndex === NOT_FOUND_INDEX ? newFileName : newFileName.slice(0, extensionSeparatorIndex);
const attachmentFileExtension = extensionSeparatorIndex === NOT_FOUND_INDEX ? "" : newFileName.slice(extensionSeparatorIndex + 1);
const activeViewFile = app.vault.getFileByPath(activeViewFilePath); const activeViewFile = app.vault.getFileByPath(activeViewFilePath);
const attachmentFilePath = await app.vault.getAvailablePathForAttachments(attachmentFileBasename, attachmentFileExtension, activeViewFile); const attachmentFilePath = await app.vault.getAvailablePathForAttachments(basename, extension, activeViewFile);
const folderSeparatorIndex = attachmentFilePath.lastIndexOf("/"); const { folderpath } = splitFolderAndFilename(attachmentFilePath);
const attachmentFolderPath = folderSeparatorIndex === NOT_FOUND_INDEX ? "" : attachmentFilePath.slice(0, folderSeparatorIndex);
return { return {
folder: attachmentFolderPath, folder: folderpath,
filepath: attachmentFilePath filepath: attachmentFilePath
}; };
}; };

View File

@@ -4041,7 +4041,11 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
if(st.newElement?.type === "freedraw") { if(st.newElement?.type === "freedraw") {
this.freedrawLastActiveTimestamp = Date.now(); this.freedrawLastActiveTimestamp = Date.now();
} }
if (st.newElement || st.editingTextElement || st.editingLinearElement) { if (
st.newElement ||
st.editingTextElement ||
(st.selectedLinearElement && st.selectedLinearElement.isEditing)
) {
this.plugin.wasPenModeActivePreviously = st.penMode; this.plugin.wasPenModeActivePreviously = st.penMode;
} }
this.viewModeEnabled = st.viewModeEnabled; this.viewModeEnabled = st.viewModeEnabled;
@@ -4083,7 +4087,7 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
/*st.resizingElement === null && /*st.resizingElement === null &&
st.newElement === null && st.newElement === null &&
st.editingGroupId === null &&*/ st.editingGroupId === null &&*/
st.editingLinearElement === null (st.selectedLinearElement === null || !st.selectedLinearElement.isEditing)
) { ) {
this.checkSceneVersion(et); this.checkSceneVersion(et);
} }

View File

@@ -765,7 +765,7 @@ textarea.excalidraw-wysiwyg, .excalidraw input {
margin-left: auto; margin-left: auto;
} }
.document-search-container { .excalidraw-search.document-search-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: var(--background-secondary); background: var(--background-secondary);
@@ -780,12 +780,12 @@ textarea.excalidraw-wysiwyg, .excalidraw input {
margin-left: 1rem; margin-left: 1rem;
} }
.document-search { .excalidraw-search .document-search {
align-items: center; align-items: center;
max-width: none; max-width: none;
} }
.search-input-container.document-search-input { .excalidraw-search .search-input-container.document-search-input {
display: flex; display: flex;
align-items: center; align-items: center;
flex: 1 1 auto; flex: 1 1 auto;
@@ -795,13 +795,13 @@ textarea.excalidraw-wysiwyg, .excalidraw input {
min-width: 0; min-width: 0;
} }
.search-input-container .clickable-icon { .excalidraw-search .search-input-container .clickable-icon {
display: flex; display: flex;
align-items: center; align-items: center;
color: var(--text-faint); color: var(--text-faint);
} }
.search-input-container input[type="text"] { .excalidraw-search .search-input-container input[type="text"] {
background: transparent; background: transparent;
border: none; border: none;
outline: none; outline: none;
@@ -812,7 +812,7 @@ textarea.excalidraw-wysiwyg, .excalidraw input {
margin: 0; margin: 0;
} }
.document-search-count { .excalidraw-search .document-search-count {
margin-left: 0.5em; margin-left: 0.5em;
color: var(--text-faint); color: var(--text-faint);
font-size: 0.95em; font-size: 0.95em;
@@ -821,13 +821,13 @@ textarea.excalidraw-wysiwyg, .excalidraw input {
text-align: right; text-align: right;
} }
.document-search-buttons { .excalidraw-search .document-search-buttons {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 2px; gap: 2px;
} }
.document-search-button { .excalidraw-search .document-search-button {
background: none; background: none;
border: none; border: none;
outline: none; outline: none;
@@ -845,12 +845,12 @@ textarea.excalidraw-wysiwyg, .excalidraw input {
justify-content: center; justify-content: center;
} }
.document-search-button:hover, .document-search-button:focus { .excalidraw-search .document-search-button:hover, .excalidraw-search .document-search-button:focus {
background: var(--background-modifier-hover); background: var(--background-modifier-hover);
color: var(--text-accent); color: var(--text-accent);
} }
.document-search-button svg { .excalidraw-search .document-search-button svg {
width: 1.3em; width: 1.3em;
height: 1.3em; height: 1.3em;
stroke: currentColor; stroke: currentColor;