fix: remove plugin reload, fix all ESLint errors, add release workflow

- Remove disablePlugin/enablePlugin reload method (Scorecard security risk)
- Add eslint-plugin-obsidianmd with typescript-eslint type-checked rules
- Fix 113 ESLint errors across all source files:
  - Replace any types with proper typing
  - Use createSpan/createEl instead of document.createElement
  - Fix floating promises, unused vars, case declarations
  - Shorten command IDs to avoid plugin name duplication
  - Use window.setTimeout instead of bare setTimeout
- Update minAppVersion to 1.4.10 (required by AbstractInputSuggest)
- Update TypeScript to 5.x, ESLint to 9.x
- Add GitHub Actions workflow for releases with artifact attestation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@gapmiss 2026-05-21 19:22:33 -05:00
parent 38b094b4d2
commit 2e2db6aad4
19 changed files with 3479 additions and 967 deletions

View file

@ -1,3 +0,0 @@
node_modules/
main.js

View file

@ -1,23 +0,0 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"env": { "node": true },
"plugins": [
"@typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parserOptions": {
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["error", { "args": "none" }],
"@typescript-eslint/ban-ts-comment": "off",
"no-prototype-builtins": "off",
"@typescript-eslint/no-empty-function": "off"
}
}

49
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,49 @@
name: Release
on:
push:
tags:
- '*.*.*'
permissions:
contents: write
id-token: write
attestations: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Attest main.js
uses: actions/attest-build-provenance@v2
with:
subject-path: main.js
- name: Attest styles.css
uses: actions/attest-build-provenance@v2
with:
subject-path: styles.css
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: |
main.js
manifest.json
styles.css
generate_release_notes: true

1
.gitignore vendored
View file

@ -22,3 +22,4 @@ data.json
.DS_Store
.hotreload
.claude

28
eslint.config.mjs Normal file
View file

@ -0,0 +1,28 @@
import tsParser from "@typescript-eslint/parser";
import tseslint from "typescript-eslint";
import obsidianmd from "eslint-plugin-obsidianmd";
export default [
{ ignores: ["node_modules/**", "main.js", "*.mjs", "package.json", "package-lock.json", "versions.json", "tsconfig.json"] },
...tseslint.configs.recommendedTypeChecked.map(config => ({
...config,
files: ["src/**/*.ts"],
})),
...obsidianmd.configs.recommended,
{
files: ["src/**/*.ts"],
languageOptions: {
parser: tsParser,
parserOptions: {
project: "./tsconfig.json",
sourceType: "module",
},
},
rules: {
"@typescript-eslint/no-unused-vars": ["error", {
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
}],
},
},
];

View file

@ -2,7 +2,7 @@
"id": "inline-callouts",
"name": "Inline Callouts",
"version": "0.1.4",
"minAppVersion": "0.15.0",
"minAppVersion": "1.4.10",
"description": "Add inline callouts/badges to notes.",
"author": "@gapmiss",
"authorUrl": "https://github.com/gapmiss",

4023
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -16,13 +16,15 @@
"license": "MIT",
"devDependencies": {
"@types/node": "^16.11.6",
"@typescript-eslint/eslint-plugin": "5.29.0",
"@typescript-eslint/parser": "5.29.0",
"@typescript-eslint/parser": "^8.0.0",
"builtin-modules": "3.3.0",
"esbuild": "^0.25.4",
"eslint": "^9.0.0",
"eslint-plugin-obsidianmd": "^0.3.0",
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"
"typescript": "^5.4.0",
"typescript-eslint": "^8.0.0"
},
"dependencies": {
"@codemirror/state": "^6.0.0",

View file

@ -219,59 +219,7 @@ const createGitCommitAndTag = (version) => {
execSync('git push', { stdio: 'inherit' });
execSync('git push --tags', { stdio: 'inherit' });
console.log('🚀 Changes pushed to GitHub');
// Create GitHub Release
try {
console.log('📦 Creating GitHub Release...');
// First check if GitHub CLI is installed
try {
execSync('gh --version', { stdio: 'pipe' });
} catch (error) {
console.log('⚠️ GitHub CLI not found. Skipping GitHub Release creation.');
console.log(' To create GitHub Releases, install GitHub CLI: https://cli.github.com/');
return;
}
// Get previous tag for changelog link
let previousTag = '';
try {
// Get all tags sorted by version (newest first)
const tagsOutput = execSync('git tag --sort=-v:refname', { encoding: 'utf-8' });
// Split by line and remove empty lines
const tags = tagsOutput.split('\n').filter(tag => tag.trim() !== '');
// If current tag is in the list, get the next one (which is the previous release)
const currentTagIndex = tags.indexOf(tagName);
if (currentTagIndex >= 0 && currentTagIndex < tags.length - 1) {
previousTag = tags[currentTagIndex + 1];
} else if (tags.length > 1 && currentTagIndex < 0) {
// If new tag is not yet in the list, take the first one
previousTag = tags[0];
}
} catch (error) {
console.warn('⚠️ Could not determine previous tag:', error.message);
}
// Create release notes with changelog link if previous tag exists
let releaseNotes = `${tagName}`;
if (previousTag) {
const repoUrl = execSync('git config --get remote.origin.url', { encoding: 'utf-8' })
.trim()
.replace(/\.git$/, '')
.replace(/^git@github\.com:/, 'https://github.com/');
releaseNotes += `\n\n**Full Changelog**: ${repoUrl}/compare/${previousTag}...${tagName}`;
}
// Create GitHub Release using GitHub CLI
const releaseCommand = `gh release create ${tagName} ${RELEASE_FILES.join(' ')} --title "Release ${tagName}" --notes "${releaseNotes}"`;
execSync(releaseCommand, { stdio: 'inherit' });
console.log(`✅ GitHub Release created: ${tagName}`);
} catch (releaseError) {
console.error('⚠️ Failed to create GitHub Release:', releaseError.message);
console.log('Release files were still committed and pushed to GitHub.');
}
console.log('📦 GitHub Actions will create the release with artifact attestations.');
return true; // Successfully created commit, tag, and pushed
} catch (error) {
console.error('❌ Error during Git operations:', error.message);

View file

@ -11,37 +11,37 @@ export class InlineCallout {
textEl: HTMLSpanElement;
constructor() {
this.newEl = document.createElement("span");
this.iconEl = document.createElement("span");
this.labelEl = document.createElement("span");
this.textEl = document.createElement("span");
this.newEl = createSpan();
this.iconEl = createSpan();
this.labelEl = createSpan();
this.textEl = createSpan();
}
public build(text: string) {
public build(text: string): HTMLElement {
// text content from <code>
let part: string = text.substring(3);
let content: string = part.slice(0, -1);
const part: string = text.substring(3);
const content: string = part.slice(0, -1);
// parts array split on pipe
let parts: any[] = content.split('|');
const parts: string[] = content.split('|');
// icon
let calloutIcon: string | null = parts[0] ? parts[0].trim().replace(/\\+$/, '').toLowerCase() : null;
const calloutIcon: string | null = parts[0] ? parts[0].trim().replace(/\\+$/, '').toLowerCase() : null;
// label
let calloutLabel: string | null = parts[1] ? parts[1].trim().replace(/\\+$/, '') : null;
const calloutLabel: string | null = parts[1] ? parts[1].trim().replace(/\\+$/, '') : null;
// color
let calloutColor: string | null = parts[2] ? parts[2].trim() : null;
const calloutColor: string | null = parts[2] ? parts[2].trim() : null;
let calloutColorStyle: string;
// no content, return <code>
if (
!content.length
|| parts.length === 0
!content.length
|| parts.length === 0
|| !calloutIcon
|| (getIconIds().indexOf('lucide-' + calloutIcon) == -1 && getIconIds().indexOf(calloutIcon) == -1) // 404, no icon found
) {
this.newEl = document.createElement("code");
this.newEl.setText(text)
return this.newEl;
const codeEl = createEl("code");
codeEl.setText(text);
return codeEl;
}
this.newEl.addClass("inline-callout");
@ -74,7 +74,7 @@ export class InlineCallout {
this.newEl.appendChild(this.iconEl);
// label?
if (calloutLabel) {
this.labelEl.setText(calloutLabel!);
this.labelEl.setText(calloutLabel);
this.newEl.appendChild(this.labelEl);
}
// color?

View file

@ -35,7 +35,7 @@ export default class InlineCalloutsPlugin extends Plugin {
settings: InlineCalloutsSettings;
public postprocessor: MarkdownPostProcessor = (el: HTMLElement, ctx: MarkdownPostProcessorContext) => {
public postprocessor: MarkdownPostProcessor = (el: HTMLElement, _ctx: MarkdownPostProcessorContext) => {
const blockToReplace = el.querySelectorAll('code')
if (blockToReplace.length === 0) return
@ -66,44 +66,43 @@ export default class InlineCalloutsPlugin extends Plugin {
this.registerEditorExtension(viewPlugin)
if (this.settings.enableSuggester) {
this.registerEditorSuggest(new EditorIconSuggest(this));
}
this.registerEditorSuggest(new EditorIconSuggest(this));
this.addCommand({
id: "new-inline-callout",
id: "new",
name: "New inline callout",
icon: "form-input",
editorCallback: (editor) => {
let modal = new NewInlineCalloutModal(this, editor);
const modal = new NewInlineCalloutModal(this, editor);
modal.open();
}
});
if (this.settings.enableEditing) {
this.addCommand({
id: "modify-inline-callout",
name: "Modify inline callout",
icon: "form-input",
editorCheckCallback: (checking, editor, view: MarkdownView) => {
let res = this.checkContextType(editor, view);
if (res) {
if (!checking) {
this.modifyInlineCallout(editor, view);
}
return true;
}
this.addCommand({
id: "modify",
name: "Modify inline callout",
icon: "form-input",
editorCheckCallback: (checking, editor, view: MarkdownView) => {
if (!this.settings.enableEditing) {
return false;
}
});
}
const res = this.checkContextType(editor, view);
if (res) {
if (!checking) {
this.modifyInlineCallout(editor, view);
}
return true;
}
return false;
}
});
this.addCommand({
id: "search-inline-callouts",
name: "Search for inline callouts",
id: "search",
name: "Search",
icon: "text-search",
callback: () => {
let modal = new SearchInlineCalloutsModal(this);
const modal = new SearchInlineCalloutsModal(this);
modal.open();
}
});
@ -111,7 +110,7 @@ export default class InlineCalloutsPlugin extends Plugin {
this.registerEvent(
this.app.workspace.on("editor-menu", (menu: Menu, editor: Editor, view: MarkdownView) => {
if (this.settings.enableEditing) {
let res = this.checkContextType(editor, view);
const res = this.checkContextType(editor, view);
if (res) {
menu.addItem(item => {
item
@ -147,7 +146,7 @@ export default class InlineCalloutsPlugin extends Plugin {
const beforeCursor = curLine.slice(0, curCh);
const afterCursor = curLine.slice(curCh);
let matcher = { type: ContextType.INLINECODE, regex: /`(\[\!\![^`]+\])`/g, enable: true }
const matcher = { type: ContextType.INLINECODE, regex: /`(\[!![^`]+\])`/g, enable: true }
const matchInfo = this.getMatchInfo(beforeCursor, afterCursor, matcher.regex);
if (matchInfo) {
@ -185,7 +184,7 @@ export default class InlineCalloutsPlugin extends Plugin {
const beforeCursor = curLine.slice(0, curCh);
const afterCursor = curLine.slice(curCh);
let matcher = { type: ContextType.INLINECODE, regex: /`(\[\!\![^`]+\])`/g, enable: true }
const matcher = { type: ContextType.INLINECODE, regex: /`(\[!![^`]+\])`/g, enable: true }
const matchInfo = this.getMatchInfo(beforeCursor, afterCursor, matcher.regex);
if (matchInfo) {
@ -207,19 +206,16 @@ export default class InlineCalloutsPlugin extends Plugin {
return;
}
const filename = file.basename;
const contextType = this.determineContextType(editor, view);
if (contextType.type == ContextType.NULL) {
new Notice("No inline callout found at current cursor position");
// eslint-disable-next-line obsidianmd/ui/sentence-case -- false positive
new Notice("No inline callout found at current cursor position.");
return;
}
const cursor = editor.getCursor();
const curLine = cursor.line;
if (contextType.type == ContextType.INLINECODE) {
let modal = new ModifyInlineCalloutModal(this, editor, contextType);
const modal = new ModifyInlineCalloutModal(this, editor, contextType);
modal.open();
return;
}
@ -244,22 +240,11 @@ export default class InlineCalloutsPlugin extends Plugin {
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData() as Partial<InlineCalloutsSettings>);
}
async saveSettings() {
await this.saveData(this.settings);
this.reload();
}
/** Reloads the plugin */
async reload() {
// @ts-ignore
await this.app.plugins.disablePlugin("inline-callouts");
// @ts-ignore
await this.app.plugins.enablePlugin("inline-callouts");
// @ts-ignore
this.app.setting.openTabById("inline-callouts").display();
}
}

View file

@ -8,18 +8,25 @@ import type InlineCalloutsPlugin from "../main";
import { IconSuggest } from '../suggest/icon';
import { InlineCallout } from '../callout/builder';
interface ContextData {
type: string;
curLine: string;
match: string | null;
range: [number, number];
}
export class ModifyInlineCalloutModal extends Modal {
public calloutIcon: string;
public calloutColor: string | undefined;
public calloutLabel: string | undefined;
previewEl: HTMLDivElement;
document: Document = window.activeDocument ?? window.document;
activeDoc: Document = window.activeDocument ?? window.document;
constructor(
private plugin: InlineCalloutsPlugin,
private editor: Editor,
private contextType: any
private contextType: ContextData
) {
super(plugin.app);
@ -28,14 +35,14 @@ export class ModifyInlineCalloutModal extends Modal {
this.onOpen = () => this.display(true);
}
private async display(focus?: boolean, clearColor?: boolean, preserveIcon?: boolean) {
private display(_focus?: boolean, clearColor?: boolean, preserveIcon?: boolean) {
const { contentEl } = this;
contentEl.empty();
this.titleEl.setText("Modify inline callout");
let content = this.contextType.match.replace("[!!", "").replace("]", "");
let parts: any[] = content.split('|');
const content = (this.contextType.match ?? '').replace("[!!", "").replace("]", "");
const parts: string[] = content.split('|');
// icon
if (!clearColor) {
@ -46,14 +53,14 @@ export class ModifyInlineCalloutModal extends Modal {
// label
if (!clearColor) {
this.calloutLabel = this.calloutLabel! ? this.calloutLabel : (parts[1] ? parts[1].trim().replace(/\\+$/, '') : undefined);
this.calloutLabel = this.calloutLabel ? this.calloutLabel : (parts[1] ? parts[1].trim().replace(/\\+$/, '') : undefined);
}
// color
if (clearColor) {
this.calloutColor = '';
} else {
this.calloutColor = this.calloutColor! ? this.calloutColor : (parts[2] ? parts[2].trim() : undefined);
this.calloutColor = this.calloutColor ? this.calloutColor : (parts[2] ? parts[2].trim() : undefined);
}
new Setting(contentEl)
@ -63,9 +70,9 @@ export class ModifyInlineCalloutModal extends Modal {
cb
.setIcon(this.calloutIcon ? this.calloutIcon : "lucide-info")
.setTooltip("Select icon")
.onClick(async (e) => {
.onClick((e) => {
e.preventDefault();
const modal = new IconSuggest(this.plugin, async (icon) => {
const modal = new IconSuggest(this.plugin, (icon) => {
this.calloutIcon = icon;
this.buildPreview();
});
@ -76,13 +83,15 @@ export class ModifyInlineCalloutModal extends Modal {
cb.buttonEl, 'keydown', (e) => {
switch (e.key) {
case "Enter":
case " ":
case " ": {
e.preventDefault();
const modal = new IconSuggest(this.plugin, async (icon) => {
const modal = new IconSuggest(this.plugin, (icon) => {
this.calloutIcon = icon;
this.buildPreview();
});
modal.open();
break;
}
}
});
});
@ -109,7 +118,7 @@ export class ModifyInlineCalloutModal extends Modal {
return `${r}, ${g}, ${b}`;
};
function rgbToHex(r: any, g: any, b: any) {
function rgbToHex(r: number, g: number, b: number) {
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b)
.toString(16)
.slice(1)
@ -138,34 +147,33 @@ export class ModifyInlineCalloutModal extends Modal {
this.calloutColor = value;
this.buildPreview();
this.display(false, false, true);
setTimeout(() => {
let dropdown: HTMLSelectElement | null = this.document.querySelector(".modify-inline-callout-modal")!.querySelector(".inline-callouts-color-dropdown .dropdown");
dropdown!.focus();
window.setTimeout(() => {
const dropdown = this.activeDoc.querySelector<HTMLSelectElement>(".modify-inline-callout-modal .inline-callouts-color-dropdown .dropdown");
dropdown?.focus();
}, 10);
}
})
})
.addColorPicker((cb) => {
let r: number = 0;
let g: number = 0;
let b: number = 0;
let r = 0;
let g = 0;
let b = 0;
if (this.calloutColor) {
let colorArr = this.calloutColor?.split(",");
r = Number(colorArr![0]);
g = Number(colorArr![1]);
b = Number(colorArr![2]);
const colorArr = this.calloutColor.split(",");
r = Number(colorArr[0] ?? 0);
g = Number(colorArr[1] ?? 0);
b = Number(colorArr[2] ?? 0);
}
cb.setValue(rgbToHex(r, g, b))
.onChange((value) => {
this.calloutColor = hexToRgb(value);
let dropdown: HTMLSelectElement | null = this.document.querySelector(".modify-inline-callout-modal")!.querySelector(".inline-callouts-color-dropdown .dropdown");
dropdown!.value = '';
const dropdown = this.activeDoc.querySelector<HTMLSelectElement>(".modify-inline-callout-modal .inline-callouts-color-dropdown .dropdown");
if (dropdown) dropdown.value = '';
this.buildPreview();
setTimeout(() => {
let picker: HTMLSelectElement | null = this.document.querySelector(".modify-inline-callout-modal")!.querySelector('input[type="color"]');
picker!.focus();
window.setTimeout(() => {
const picker = this.activeDoc.querySelector<HTMLInputElement>(".modify-inline-callout-modal input[type='color']");
picker?.focus();
}, 10);
});
})
.addExtraButton((ex) => {
@ -173,7 +181,6 @@ export class ModifyInlineCalloutModal extends Modal {
.setTooltip('Reset to no color')
.onClick(() => {
this.calloutColor = '';
this.calloutIcon = this.calloutIcon;
this.display(false, true);
})
});
@ -193,8 +200,8 @@ export class ModifyInlineCalloutModal extends Modal {
.setCta()
.onClick(() => {
try {
let firstPipe: string = '';
let secondPipe: string = '';
let firstPipe = '';
let secondPipe = '';
if (this.calloutLabel !== undefined || this.calloutColor !== undefined) {
firstPipe = "|";
@ -207,14 +214,14 @@ export class ModifyInlineCalloutModal extends Modal {
secondPipe = "|";
}
let cursor = this.editor.getCursor();
const cursor = this.editor.getCursor();
this.editor.replaceRange(
`\`[!!${this.calloutIcon.replace("lucide-", "")}${firstPipe + (this.calloutLabel !== undefined ? this.calloutLabel : "")}${this.calloutColor ? secondPipe + this.calloutColor : ""}]\``,
{ line: cursor.line, ch: this.contextType.range?.[0] }, { line: cursor.line, ch: this.contextType.range?.[1] }
{ line: cursor.line, ch: this.contextType.range[0] }, { line: cursor.line, ch: this.contextType.range[1] }
);
} catch (e) {
console.log(e)
console.error(e);
new Notice(
"There was an issue saving the inline callout. Check the developer console for details."
);
@ -229,7 +236,7 @@ export class ModifyInlineCalloutModal extends Modal {
this.previewEl.empty();
this.previewEl.setAttr("style", "margin-bottom: 1em;");
const inlineCallout = new InlineCallout();
let newEl = inlineCallout.build('[!!' + this.calloutIcon + '|' + (this.calloutLabel ? this.calloutLabel : '') + '|' + this.calloutColor + ']');
const newEl = inlineCallout.build('[!!' + this.calloutIcon + '|' + (this.calloutLabel ? this.calloutLabel : '') + '|' + this.calloutColor + ']');
this.previewEl.appendChild(newEl);
}

View file

@ -14,7 +14,7 @@ export class NewInlineCalloutModal extends Modal {
public calloutColor: string | undefined;
public calloutLabel: string | undefined;
previewEl: HTMLDivElement;
document: Document = window.activeDocument ?? window.document;
activeDoc: Document = window.activeDocument ?? window.document;
constructor(
private plugin: InlineCalloutsPlugin,
@ -32,7 +32,7 @@ export class NewInlineCalloutModal extends Modal {
}
}
private async display(focus?: boolean, clearColor?: boolean) {
private display(_focus?: boolean, _clearColor?: boolean) {
const { contentEl } = this;
contentEl.empty();
@ -45,9 +45,9 @@ export class NewInlineCalloutModal extends Modal {
cb
.setIcon(this.calloutIcon)
.setTooltip("Select icon")
.onClick(async (e) => {
.onClick((e) => {
e.preventDefault();
const modal = new IconSuggest(this.plugin, async (icon) => {
const modal = new IconSuggest(this.plugin, (icon) => {
this.calloutIcon = icon;
this.buildPreview();
});
@ -58,13 +58,15 @@ export class NewInlineCalloutModal extends Modal {
cb.buttonEl, 'keydown', (e) => {
switch (e.key) {
case "Enter":
case " ":
case " ": {
e.preventDefault();
const modal = new IconSuggest(this.plugin, async (icon) => {
const modal = new IconSuggest(this.plugin, (icon) => {
this.calloutIcon = icon;
this.buildPreview();
});
modal.open();
break;
}
}
});
});
@ -73,7 +75,7 @@ export class NewInlineCalloutModal extends Modal {
.setName("Label")
.setDesc("Default: blank")
.addText((t) => {
t.setValue(this.calloutLabel!);
t.setValue(this.calloutLabel ?? '');
t.onChange((v) => {
this.calloutLabel = v;
this.buildPreview();
@ -109,9 +111,9 @@ export class NewInlineCalloutModal extends Modal {
this.calloutColor = value;
this.buildPreview();
this.display(false, false);
setTimeout(() => {
let dropdown: HTMLSelectElement | null = this.document.querySelector(".new-inline-callout-modal")!.querySelector(".inline-callouts-color-dropdown .dropdown");
dropdown!.focus();
window.setTimeout(() => {
const dropdown = this.activeDoc.querySelector<HTMLSelectElement>(".new-inline-callout-modal .inline-callouts-color-dropdown .dropdown");
dropdown?.focus();
}, 10);
}
})
@ -120,12 +122,12 @@ export class NewInlineCalloutModal extends Modal {
cb.setValue(this.calloutColor ?? '#000000')
.onChange((value) => {
this.calloutColor = hexToRgb(value);
let dropdown: HTMLSelectElement | null = this.document.querySelector(".new-inline-callout-modal")!.querySelector(".inline-callouts-color-dropdown .dropdown");
dropdown!.value = '';
const dropdown = this.activeDoc.querySelector<HTMLSelectElement>(".new-inline-callout-modal .inline-callouts-color-dropdown .dropdown");
if (dropdown) dropdown.value = '';
this.buildPreview();
setTimeout(() => {
let picker: HTMLSelectElement | null = this.document.querySelector(".new-inline-callout-modal")!.querySelector('input[type="color"]');
picker!.focus();
window.setTimeout(() => {
const picker = this.activeDoc.querySelector<HTMLInputElement>(".new-inline-callout-modal input[type='color']");
picker?.focus();
}, 10);
});
})
@ -134,7 +136,6 @@ export class NewInlineCalloutModal extends Modal {
.setTooltip('Reset to no color')
.onClick(() => {
this.calloutColor = '';
this.calloutIcon = this.calloutIcon;
this.display(false, true);
})
});
@ -154,8 +155,8 @@ export class NewInlineCalloutModal extends Modal {
.setCta()
.onClick(() => {
try {
let firstPipe: string = '';
let secondPipe: string = '';
let firstPipe = '';
let secondPipe = '';
if (this.calloutLabel !== undefined || this.calloutColor !== undefined) {
firstPipe = "|";
}
@ -166,13 +167,13 @@ export class NewInlineCalloutModal extends Modal {
) {
secondPipe = "|";
}
let trailingSpace: string = this.plugin.settings.enableTraiingSpace ? " " : "";
const trailingSpace = this.plugin.settings.enableTraiingSpace ? " " : "";
this.editor.getDoc().replaceSelection(
`\`[!!${this.calloutIcon.replace("lucide-", "")}${firstPipe + (this.calloutLabel !== undefined ? this.calloutLabel : "")}${this.calloutColor ? secondPipe + this.calloutColor : ""}]\`${trailingSpace}`,
);
// const cursor = this.editor.getCursor();
} catch (e) {
console.log(e)
console.error(e)
new Notice(
"There was an issue inserting the inline callout. Please check the developer console for details."
);
@ -188,7 +189,7 @@ export class NewInlineCalloutModal extends Modal {
this.previewEl.empty();
this.previewEl.setAttr("style", "margin-bottom: 1em;");
const inlineCallout = new InlineCallout();
let newEl = inlineCallout.build('[!!' + this.calloutIcon + '|' + (this.calloutLabel ? this.calloutLabel : '') + '|' + this.calloutColor + ']');
const newEl = inlineCallout.build('[!!' + this.calloutIcon + '|' + (this.calloutLabel ? this.calloutLabel : '') + '|' + this.calloutColor + ']');
this.previewEl.appendChild(newEl);
}

View file

@ -2,7 +2,6 @@ import {
Modal,
Notice,
Setting,
TextComponent,
getIconIds
} from 'obsidian';
import { InputIconSuggest } from '../suggest/inputIcon';
@ -22,10 +21,9 @@ export class SearchInlineCalloutsModal extends Modal {
this.onOpen = () => this.display(true);
}
private async display(focus?: boolean) {
private display(_focus?: boolean) {
const { contentEl } = this;
contentEl.empty();
let input: TextComponent;
this.titleEl.setText("Search inline callouts");
new Setting(contentEl)
@ -33,7 +31,6 @@ export class SearchInlineCalloutsModal extends Modal {
.setDesc('Enter text to find an icon to search for.')
.setClass('search-icon-input')
.addSearch((t) => {
input = t;
t.setValue('')
.onChange((v) => {
this.calloutIcon = v;
@ -59,7 +56,7 @@ export class SearchInlineCalloutsModal extends Modal {
);
}
} catch (e) {
console.log(e)
console.error(e)
new Notice(
"There was an issue with your search query. Please check the developer console for details.",
5000

View file

@ -45,7 +45,7 @@ export class InlineCalloutsSettingTab extends PluginSettingTab {
new Setting(containerEl)
.setName('Enable editing command/menu')
.setDesc('In editing view (source & live preview modes), enable "Modify inline callout" command and context menu option.')
.setDesc('In editing view (source & live preview modes), enable "modify inline callout" command and context menu option.')
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.enableEditing)

View file

@ -24,6 +24,9 @@ export class EditorIconSuggest extends EditorSuggest<string> {
}
onTrigger(cursor: EditorPosition, editor: Editor, _: TFile): EditorSuggestTriggerInfo | null {
if (!this.plugin.settings.enableSuggester) {
return null;
}
const sub = editor.getLine(cursor.line).substring(0, cursor.ch);
const match = sub.match(/!!\S+$/)?.first();
if (match) {
@ -55,7 +58,7 @@ export class EditorIconSuggest extends EditorSuggest<string> {
selectSuggestion(suggestion: string): void {
if (this.context) {
(this.context.editor as Editor).replaceRange('!!' + suggestion.replace("lucide-", ""), this.context.start, this.context.end);
this.context.editor.replaceRange('!!' + suggestion.replace("lucide-", ""), this.context.start, this.context.end);
}
}
}

View file

@ -54,7 +54,7 @@ export class IconSuggest extends SuggestModal<IconName> {
iconWrapper.appendChild(iconName);
}
onChooseSuggestion(item: string, evt: MouseEvent | KeyboardEvent) {
onChooseSuggestion(item: string, _evt: MouseEvent | KeyboardEvent) {
setIcon(activeDocument.querySelector('[data-note-toolbar-no-icon]')!, item);
IconSuggest.icon = item;
this.callback(item);

View file

@ -4,7 +4,7 @@ import {
setIcon
} from "obsidian";
export class InputIconSuggest extends AbstractInputSuggest<String> {
export class InputIconSuggest extends AbstractInputSuggest<string> {
textInputEl: HTMLInputElement;
constructor(

View file

@ -40,10 +40,10 @@ export const viewPlugin = ViewPlugin.fromClass(class {
const startOfLine = line.from;
const endOfLine = line.to;
let currentLine = false;
let _currentLine = false;
currentSelections.forEach((r) => {
if (r.to >= startOfLine && r.from <= endOfLine) {
currentLine = true;
_currentLine = true;
return;
}
});
@ -69,7 +69,7 @@ export const viewPlugin = ViewPlugin.fromClass(class {
return builder.finish();
}
}, {
decorations: (v: any) => v.decorations,
decorations: (v: { decorations: DecorationSet }) => v.decorations,
})
class InlineCalloutWidget extends WidgetType {
@ -77,7 +77,7 @@ class InlineCalloutWidget extends WidgetType {
super()
}
toDOM(view: EditorView): HTMLElement {
toDOM(_view: EditorView): HTMLElement {
let text: string = this.callout[0].substring(1).substring(this.callout[0].length - 2, 0);
const inlineCallout = new InlineCallout();
let newEl = inlineCallout.build(text);