mirror of
https://github.com/jamescliffordspratt/macros.git
synced 2026-07-22 05:46:53 +00:00
Type metric collections (MacroscalcMetric/MetricValue) end-to-end
This commit is contained in:
parent
6bc2364286
commit
0bfbe9934f
17 changed files with 75 additions and 69 deletions
1
__synctest.txt
Normal file
1
__synctest.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
synctest-1782576047
|
||||
|
|
@ -236,7 +236,7 @@ export class I18nManager {
|
|||
// FIX: Use typed interfaces instead of 'any'
|
||||
const obsidianLocale =
|
||||
this.getMomentLocale() || // Use existing safe method
|
||||
document.documentElement.lang ||
|
||||
activeDocument.documentElement.lang ||
|
||||
(this.app as ObsidianAppWithConfig).vault?.config?.userInterfaceMode ||
|
||||
(this.app as ObsidianAppWithConfig).locale;
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ export class RefreshManager {
|
|||
}
|
||||
|
||||
// Process macroscalc containers
|
||||
const macroscalcElements = document.querySelectorAll('[data-macroscalc-ids]');
|
||||
const macroscalcElements = activeDocument.querySelectorAll('[data-macroscalc-ids]');
|
||||
macroscalcElements.forEach((el) => {
|
||||
const idsAttr = el.getAttribute('data-macroscalc-ids');
|
||||
if (idsAttr) {
|
||||
|
|
@ -149,7 +149,7 @@ export class RefreshManager {
|
|||
async refreshAllMacroscalc(): Promise<void> {
|
||||
try {
|
||||
// First, find all macroscalc elements in the DOM
|
||||
const macroscalcElements = document.querySelectorAll('[data-macroscalc-ids]');
|
||||
const macroscalcElements = activeDocument.querySelectorAll('[data-macroscalc-ids]');
|
||||
|
||||
if (macroscalcElements.length > 0) {
|
||||
this.plugin.logger.debug(
|
||||
|
|
|
|||
|
|
@ -97,7 +97,9 @@ export class RenameWatcher {
|
|||
}
|
||||
} catch (error) {
|
||||
this.plugin.logger.error('Error handling file rename:', error);
|
||||
this.plugin.app.workspace.trigger('notice', t('rename.error', { error: error.message }));
|
||||
this.plugin.app.workspace.trigger('notice', t('rename.error', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +177,9 @@ export class RenameWatcher {
|
|||
}
|
||||
} catch (error) {
|
||||
this.plugin.logger.error('Error performing rename operation:', error);
|
||||
this.plugin.app.workspace.trigger('notice', t('rename.error', { error: error.message }));
|
||||
this.plugin.app.workspace.trigger('notice', t('rename.error', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +228,7 @@ export class RenameWatcher {
|
|||
this.plugin.logger.error('Error reverting file rename:', error);
|
||||
this.plugin.app.workspace.trigger(
|
||||
'notice',
|
||||
t('rename.revertError', { error: error.message })
|
||||
t('rename.revertError', { error: error instanceof Error ? error.message : String(error) })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -540,7 +540,7 @@ export class RowRenderer {
|
|||
|
||||
try {
|
||||
// Find the macros block ID from the current context
|
||||
const macrosContainer = document.querySelector('[data-macros-id]');
|
||||
const macrosContainer = activeDocument.querySelector('[data-macros-id]');
|
||||
const macrosId = macrosContainer?.getAttribute('data-macros-id');
|
||||
|
||||
if (!macrosId) {
|
||||
|
|
@ -876,7 +876,7 @@ export class RowRenderer {
|
|||
const cell = tableRow.insertCell();
|
||||
cell.classList.add(CLASS_NAMES.MACRO.CELL, `${macroType}-cell`);
|
||||
|
||||
const content = document.createElement('div');
|
||||
const content = activeDocument.createElement('div');
|
||||
|
||||
const total = row.protein + row.fat + row.carbs;
|
||||
const percentageOfFood = total > 0 ? Math.round((value / total) * 100) : 0;
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ export class TableHeader {
|
|||
|
||||
public initializeButtonState(): void {
|
||||
try {
|
||||
const sections = document.querySelectorAll('.meal-header');
|
||||
const sections = activeDocument.querySelectorAll('.meal-header');
|
||||
|
||||
if (sections.length === 0) {
|
||||
this.isCollapsed = false;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import MacrosPlugin from '../../main';
|
||||
import { MetricValue, MacroscalcMetric } from './metrics/MetricsRegistry';
|
||||
import {
|
||||
formatCalories,
|
||||
formatGrams,
|
||||
|
|
@ -189,7 +190,7 @@ export class MacrosCalcRenderer {
|
|||
const displayOptions = this.getDisplayOptions();
|
||||
|
||||
// Create a document fragment to batch DOM operations
|
||||
const fragment = document.createDocumentFragment();
|
||||
const fragment = activeDocument.createDocumentFragment();
|
||||
this.el.empty();
|
||||
|
||||
// Load state from MacrosState
|
||||
|
|
@ -455,7 +456,7 @@ export class MacrosCalcRenderer {
|
|||
const metricResults = registry.calculateMetrics(metricsData, this.metricsConfigs);
|
||||
|
||||
// Group metrics by category
|
||||
const categorizedMetrics = new Map<string, { metric: unknown; values: unknown[] }[]>();
|
||||
const categorizedMetrics = new Map<string, { metric: MacroscalcMetric; values: MetricValue[] }[]>();
|
||||
|
||||
for (const [metricId, values] of metricResults) {
|
||||
const metric = registry.get(metricId);
|
||||
|
|
@ -527,7 +528,7 @@ export class MacrosCalcRenderer {
|
|||
|
||||
private createCustomMetricCard(
|
||||
container: HTMLElement,
|
||||
metricValue: unknown,
|
||||
metricValue: MetricValue,
|
||||
category?: string
|
||||
): void {
|
||||
const card = container.createDiv({
|
||||
|
|
@ -1005,7 +1006,7 @@ export class MacrosCalcRenderer {
|
|||
];
|
||||
|
||||
detailHeaderData.forEach((headerInfo) => {
|
||||
const th = document.createElement('th');
|
||||
const th = activeDocument.createElement('th');
|
||||
const desktopSpan = createEl('span', {
|
||||
cls: 'header-text-desktop',
|
||||
text: headerInfo.text,
|
||||
|
|
@ -1708,7 +1709,7 @@ export class MacrosCalcRenderer {
|
|||
this.plugin.logger.debug('Chart created successfully:', chart);
|
||||
|
||||
const resizeHandler = () => {
|
||||
if (document.contains(chartCanvas)) {
|
||||
if (activeDocument.contains(chartCanvas)) {
|
||||
chart.resize();
|
||||
}
|
||||
};
|
||||
|
|
@ -1747,7 +1748,7 @@ export class MacrosCalcRenderer {
|
|||
t('table.headers.fat'),
|
||||
t('table.headers.carbs'),
|
||||
].forEach((header) => {
|
||||
const th = document.createElement('th');
|
||||
const th = activeDocument.createElement('th');
|
||||
th.textContent = header;
|
||||
headerRow.appendChild(th);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ export function registerMacrosCalcProcessor(plugin: MacrosPlugin): void {
|
|||
// Setup cleanup
|
||||
plugin.registerEvent(
|
||||
plugin.app.workspace.on('layout-change', () => {
|
||||
if (!el.isConnected || !document.contains(el)) {
|
||||
if (!el.isConnected || !activeDocument.contains(el)) {
|
||||
plugin.macroService._activeMacrosCalcRenderers.delete(renderer);
|
||||
}
|
||||
})
|
||||
|
|
@ -131,7 +131,7 @@ async function forceRefreshAllRenderers(plugin: MacrosPlugin): Promise<void> {
|
|||
plugin.logger.debug(`Force refreshing all macroscalc renderers`);
|
||||
|
||||
// First, find all macroscalc elements in the DOM
|
||||
const macroscalcElements = document.querySelectorAll('[data-macroscalc-ids]');
|
||||
const macroscalcElements = activeDocument.querySelectorAll('[data-macroscalc-ids]');
|
||||
|
||||
if (macroscalcElements.length > 0) {
|
||||
plugin.logger.debug(`Found ${macroscalcElements.length} macroscalc elements to refresh`);
|
||||
|
|
@ -193,7 +193,7 @@ async function forceRefreshAllRenderers(plugin: MacrosPlugin): Promise<void> {
|
|||
|
||||
for (const renderer of plugin.macroService._activeMacrosCalcRenderers) {
|
||||
// Check if the renderer's element is still in the DOM
|
||||
if (renderer.el && renderer.el.isConnected && document.contains(renderer.el)) {
|
||||
if (renderer.el && renderer.el.isConnected && activeDocument.contains(renderer.el)) {
|
||||
validRenderers.add(renderer);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Modal } from 'obsidian';
|
||||
import MacrosPlugin from '../../../main';
|
||||
import { MetricsRegistry, MetricConfig } from './MetricsRegistry';
|
||||
import { MetricsRegistry, MetricConfig, MacroscalcMetric } from './MetricsRegistry';
|
||||
import { t } from '../../../lang/I18nManager';
|
||||
|
||||
export class MetricsEditModal extends Modal {
|
||||
|
|
@ -124,8 +124,8 @@ export class MetricsEditModal extends Modal {
|
|||
return categoryNames[categoryKey] || categoryKey.toUpperCase();
|
||||
}
|
||||
|
||||
private groupMetricsByCategory(): Record<string, unknown[]> {
|
||||
const categories: Record<string, unknown[]> = {};
|
||||
private groupMetricsByCategory(): Record<string, MacroscalcMetric[]> {
|
||||
const categories: Record<string, MacroscalcMetric[]> = {};
|
||||
|
||||
this.registry.getAll().forEach((metric) => {
|
||||
const category = metric.category || 'other';
|
||||
|
|
@ -138,7 +138,7 @@ export class MetricsEditModal extends Modal {
|
|||
return categories;
|
||||
}
|
||||
|
||||
private renderMetricSetting(container: HTMLElement, metric: unknown): void {
|
||||
private renderMetricSetting(container: HTMLElement, metric: MacroscalcMetric): void {
|
||||
// Find the working config for this metric (should always exist now)
|
||||
const config = this.workingConfigs.find((c) => c.id === metric.id);
|
||||
if (!config) {
|
||||
|
|
@ -211,7 +211,7 @@ export class MetricsEditModal extends Modal {
|
|||
private updateConfigVisibility(
|
||||
settingItem: HTMLElement,
|
||||
enabled: boolean,
|
||||
metric: unknown,
|
||||
metric: MacroscalcMetric,
|
||||
config: MetricConfig
|
||||
): void {
|
||||
// Remove existing config container
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export class AdherenceMetric implements MacroscalcMetric {
|
|||
.addSlider((slider) => {
|
||||
slider
|
||||
.setLimits(5, 25, 5)
|
||||
.setValue(config.calorieTolerance || 10)
|
||||
.setValue((config.calorieTolerance as number) || 10)
|
||||
.setDynamicTooltip()
|
||||
.onChange((value) => {
|
||||
config.calorieTolerance = value;
|
||||
|
|
@ -38,7 +38,7 @@ export class AdherenceMetric implements MacroscalcMetric {
|
|||
.addSlider((slider) => {
|
||||
slider
|
||||
.setLimits(5, 25, 5)
|
||||
.setValue(config.proteinTolerance || 10)
|
||||
.setValue((config.proteinTolerance as number) || 10)
|
||||
.setDynamicTooltip()
|
||||
.onChange((value) => {
|
||||
config.proteinTolerance = value;
|
||||
|
|
@ -52,7 +52,7 @@ export class AdherenceMetric implements MacroscalcMetric {
|
|||
.addSlider((slider) => {
|
||||
slider
|
||||
.setLimits(5, 25, 5)
|
||||
.setValue(config.fatTolerance || 15)
|
||||
.setValue((config.fatTolerance as number) || 15)
|
||||
.setDynamicTooltip()
|
||||
.onChange((value) => {
|
||||
config.fatTolerance = value;
|
||||
|
|
@ -66,7 +66,7 @@ export class AdherenceMetric implements MacroscalcMetric {
|
|||
.addSlider((slider) => {
|
||||
slider
|
||||
.setLimits(5, 25, 5)
|
||||
.setValue(config.carbsTolerance || 15)
|
||||
.setValue((config.carbsTolerance as number) || 15)
|
||||
.setDynamicTooltip()
|
||||
.onChange((value) => {
|
||||
config.carbsTolerance = value;
|
||||
|
|
@ -100,10 +100,10 @@ export class AdherenceMetric implements MacroscalcMetric {
|
|||
const adherenceConfig = data.configs.find((c) => c.id === 'adherence');
|
||||
if (adherenceConfig && adherenceConfig.settings) {
|
||||
config = {
|
||||
calorieTolerance: adherenceConfig.settings.calorieTolerance || 10,
|
||||
proteinTolerance: adherenceConfig.settings.proteinTolerance || 10,
|
||||
fatTolerance: adherenceConfig.settings.fatTolerance || 15,
|
||||
carbsTolerance: adherenceConfig.settings.carbsTolerance || 15,
|
||||
calorieTolerance: (adherenceConfig.settings.calorieTolerance as number) || 10,
|
||||
proteinTolerance: (adherenceConfig.settings.proteinTolerance as number) || 10,
|
||||
fatTolerance: (adherenceConfig.settings.fatTolerance as number) || 15,
|
||||
carbsTolerance: (adherenceConfig.settings.carbsTolerance as number) || 15,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ class SortableTabOrder extends Component {
|
|||
private setupEventListeners(): void {
|
||||
this.registerDomEvent(this.listEl, 'dragstart', (e: DragEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
const listItem = target.closest('.sortable-tab-item');
|
||||
const listItem = target.closest('.sortable-tab-item') as HTMLElement | null;
|
||||
|
||||
if (listItem) {
|
||||
this.draggedItem = listItem;
|
||||
|
|
@ -194,7 +194,7 @@ class SortableTabOrder extends Component {
|
|||
e.preventDefault();
|
||||
|
||||
const target = e.target as HTMLElement;
|
||||
const listItem = target.closest('.sortable-tab-item');
|
||||
const listItem = target.closest('.sortable-tab-item') as HTMLElement | null;
|
||||
|
||||
if (listItem && listItem !== this.draggedItem) {
|
||||
this.listEl.querySelectorAll('.sortable-tab-item').forEach((item) => {
|
||||
|
|
@ -218,7 +218,7 @@ class SortableTabOrder extends Component {
|
|||
if (!this.draggedItem) return;
|
||||
|
||||
const target = e.target as HTMLElement;
|
||||
const dropTarget = target.closest('.sortable-tab-item');
|
||||
const dropTarget = target.closest('.sortable-tab-item') as HTMLElement | null;
|
||||
|
||||
if (dropTarget && dropTarget !== this.draggedItem) {
|
||||
const dropIndex = parseInt(dropTarget.dataset.index || '0');
|
||||
|
|
@ -386,7 +386,7 @@ export class NutritionalSettingTab extends PluginSettingTab {
|
|||
}
|
||||
|
||||
// Re-render content
|
||||
const contentEl = this.containerEl.querySelector('.macros-settings-content');
|
||||
const contentEl = this.containerEl.querySelector('.macros-settings-content') as HTMLElement | null;
|
||||
if (contentEl) {
|
||||
this.renderActiveTab(contentEl);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,21 +32,21 @@ export class ContextMenuManager {
|
|||
* Hide all active tooltips before showing context menu
|
||||
*/
|
||||
private hideActiveTooltips(): void {
|
||||
const activeTooltips = document.querySelectorAll('.macro-tooltip');
|
||||
const activeTooltips = activeDocument.querySelectorAll('.macro-tooltip');
|
||||
activeTooltips.forEach((tooltip) => {
|
||||
(tooltip as HTMLElement).style.display = 'none';
|
||||
});
|
||||
|
||||
document.body.classList.add('context-menu-open');
|
||||
activeDocument.body.classList.add('context-menu-open');
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-enable tooltips after context menu closes
|
||||
*/
|
||||
private restoreTooltips(): void {
|
||||
document.body.classList.remove('context-menu-open');
|
||||
activeDocument.body.classList.remove('context-menu-open');
|
||||
|
||||
const hiddenTooltips = document.querySelectorAll('.macro-tooltip');
|
||||
const hiddenTooltips = activeDocument.querySelectorAll('.macro-tooltip');
|
||||
hiddenTooltips.forEach((tooltip) => {
|
||||
(tooltip as HTMLElement).style.display = '';
|
||||
});
|
||||
|
|
@ -57,7 +57,7 @@ export class ContextMenuManager {
|
|||
*/
|
||||
private applyMenuStyling(): void {
|
||||
window.setTimeout(() => {
|
||||
const menuElement = document.querySelector('.menu');
|
||||
const menuElement = activeDocument.querySelector('.menu');
|
||||
if (menuElement) {
|
||||
menuElement.setAttribute('data-macros-plugin', 'true');
|
||||
}
|
||||
|
|
@ -244,7 +244,7 @@ export class ContextMenuManager {
|
|||
};
|
||||
|
||||
window.setTimeout(() => {
|
||||
if (!document.querySelector('.menu[data-macros-plugin="true"]')) {
|
||||
if (!activeDocument.querySelector('.menu[data-macros-plugin="true"]')) {
|
||||
this.restoreTooltips();
|
||||
}
|
||||
}, 100);
|
||||
|
|
@ -264,7 +264,7 @@ export class ContextMenuManager {
|
|||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
observer.observe(activeDocument.body, { childList: true, subtree: true });
|
||||
|
||||
window.setTimeout(() => {
|
||||
observer.disconnect();
|
||||
|
|
@ -403,7 +403,7 @@ export class ContextMenuManager {
|
|||
};
|
||||
|
||||
window.setTimeout(() => {
|
||||
if (!document.querySelector('.menu[data-macros-plugin="true"]')) {
|
||||
if (!activeDocument.querySelector('.menu[data-macros-plugin="true"]')) {
|
||||
this.restoreTooltips();
|
||||
}
|
||||
}, 100);
|
||||
|
|
@ -423,7 +423,7 @@ export class ContextMenuManager {
|
|||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
observer.observe(activeDocument.body, { childList: true, subtree: true });
|
||||
|
||||
window.setTimeout(() => {
|
||||
observer.disconnect();
|
||||
|
|
@ -589,7 +589,7 @@ export class ContextMenuManager {
|
|||
};
|
||||
|
||||
window.setTimeout(() => {
|
||||
if (!document.querySelector('.menu[data-macros-plugin="true"]')) {
|
||||
if (!activeDocument.querySelector('.menu[data-macros-plugin="true"]')) {
|
||||
this.restoreTooltips();
|
||||
}
|
||||
}, 100);
|
||||
|
|
@ -609,7 +609,7 @@ export class ContextMenuManager {
|
|||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
observer.observe(activeDocument.body, { childList: true, subtree: true });
|
||||
|
||||
window.setTimeout(() => {
|
||||
observer.disconnect();
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export class FoodResultsModal extends Modal {
|
|||
this.loadPage(0);
|
||||
|
||||
// Add document-level event handling - register with component for cleanup
|
||||
this.component.registerDomEvent(document, 'keydown', this.handleKeyNav);
|
||||
this.component.registerDomEvent(activeDocument, 'keydown', this.handleKeyNav);
|
||||
}
|
||||
|
||||
onClose() {
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ export class RenameConfirmationModal extends Modal {
|
|||
}
|
||||
|
||||
private addStyles(): void {
|
||||
const styleEl = document.createElement('style');
|
||||
const styleEl = activeDocument.createElement('style');
|
||||
styleEl.textContent = `
|
||||
.rename-summary {
|
||||
margin-bottom: 1rem;
|
||||
|
|
@ -311,11 +311,11 @@ export class RenameConfirmationModal extends Modal {
|
|||
border-top: 1px solid var(--background-modifier-border);
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(styleEl);
|
||||
activeDocument.head.appendChild(styleEl);
|
||||
|
||||
// Clean up styles when modal closes
|
||||
this.onClose = () => {
|
||||
document.head.removeChild(styleEl);
|
||||
activeDocument.head.removeChild(styleEl);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ export class BarcodeScanner extends Component {
|
|||
if (!this.video || !this.codeReader) return;
|
||||
|
||||
if (!this.canvas) {
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.canvas = activeDocument.createElement('canvas');
|
||||
this.context = this.canvas.getContext('2d', { willReadFrequently: true });
|
||||
}
|
||||
|
||||
|
|
@ -492,7 +492,7 @@ export class BarcodeScanner extends Component {
|
|||
} = {}
|
||||
): Promise<BarcodeResult | null> {
|
||||
// Create optimized canvas with willReadFrequently flag to suppress warnings
|
||||
const canvas = document.createElement('canvas');
|
||||
const canvas = activeDocument.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d', {
|
||||
willReadFrequently: true, // This fixes the Canvas2D warnings
|
||||
});
|
||||
|
|
@ -739,7 +739,7 @@ export class BarcodeScannerModal extends Modal {
|
|||
cls: 'barcode-scan-upload-btn',
|
||||
});
|
||||
|
||||
this.uploadInput = document.createElement('input');
|
||||
this.uploadInput = activeDocument.createElement('input');
|
||||
this.uploadInput.type = 'file';
|
||||
this.uploadInput.accept = 'image/*';
|
||||
this.uploadInput.capture = 'environment';
|
||||
|
|
|
|||
|
|
@ -73,12 +73,12 @@ export class ZXingLoader {
|
|||
async (): Promise<ZXingLibrary> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Remove any existing script first
|
||||
const existingScript = document.querySelector('script[src*="zxing"]');
|
||||
const existingScript = activeDocument.querySelector('script[src*="zxing"]');
|
||||
if (existingScript) {
|
||||
existingScript.remove();
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
const script = activeDocument.createElement('script');
|
||||
script.src = 'https://unpkg.com/@zxing/browser@0.1.1/lib/index.min.js';
|
||||
script.onload = () => {
|
||||
// Check multiple possible global names
|
||||
|
|
@ -92,7 +92,7 @@ export class ZXingLoader {
|
|||
script.onerror = (_error) => {
|
||||
reject(new Error('Failed to load ZXing browser from CDN'));
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
activeDocument.head.appendChild(script);
|
||||
});
|
||||
},
|
||||
|
||||
|
|
@ -100,12 +100,12 @@ export class ZXingLoader {
|
|||
async (): Promise<ZXingLibrary> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Remove any existing script first
|
||||
const existingScript = document.querySelector('script[src*="zxing"]');
|
||||
const existingScript = activeDocument.querySelector('script[src*="zxing"]');
|
||||
if (existingScript) {
|
||||
existingScript.remove();
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
const script = activeDocument.createElement('script');
|
||||
script.src = 'https://unpkg.com/@zxing/library@0.20.0/umd/index.min.js';
|
||||
script.onload = () => {
|
||||
// Check multiple possible global names
|
||||
|
|
@ -119,14 +119,14 @@ export class ZXingLoader {
|
|||
script.onerror = (_error) => {
|
||||
reject(new Error('Failed to load ZXing from CDN'));
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
activeDocument.head.appendChild(script);
|
||||
});
|
||||
},
|
||||
|
||||
// Method 5: Try alternative CDN
|
||||
async (): Promise<ZXingLibrary> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
const script = activeDocument.createElement('script');
|
||||
script.src = 'https://cdn.jsdelivr.net/npm/@zxing/library@0.20.0/umd/index.min.js';
|
||||
script.onload = () => {
|
||||
const ZXing = window.ZXing || window.ZXingLibrary;
|
||||
|
|
@ -137,7 +137,7 @@ export class ZXingLoader {
|
|||
}
|
||||
};
|
||||
script.onerror = () => reject(new Error('Failed to load ZXing from jsdelivr'));
|
||||
document.head.appendChild(script);
|
||||
activeDocument.head.appendChild(script);
|
||||
});
|
||||
},
|
||||
];
|
||||
|
|
@ -244,7 +244,7 @@ export class ZXingLoader {
|
|||
|
||||
// Add decodeFromImageData method
|
||||
reader.decodeFromImageData = async function (imageData: ImageData): Promise<ZXingResult> {
|
||||
const canvas = document.createElement('canvas');
|
||||
const canvas = activeDocument.createElement('canvas');
|
||||
canvas.width = imageData.width;
|
||||
canvas.height = imageData.height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
|
@ -261,7 +261,7 @@ export class ZXingLoader {
|
|||
|
||||
// Add decodeFromImageElement method
|
||||
reader.decodeFromImageElement = async function (img: HTMLImageElement): Promise<ZXingResult> {
|
||||
const canvas = document.createElement('canvas');
|
||||
const canvas = activeDocument.createElement('canvas');
|
||||
canvas.width = img.width || img.naturalWidth;
|
||||
canvas.height = img.height || img.naturalHeight;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ function detectMobileDevice(): boolean {
|
|||
|
||||
function ensureTooltipEl(): HTMLDivElement {
|
||||
if (!tooltipEl) {
|
||||
tooltipEl = document.createElement('div');
|
||||
tooltipEl = activeDocument.createElement('div');
|
||||
tooltipEl.className = 'macro-tooltip macro-tooltip-hidden';
|
||||
tooltipEl.setAttribute('style', '--x: -9999px; --y: -9999px;');
|
||||
document.body.appendChild(tooltipEl);
|
||||
activeDocument.body.appendChild(tooltipEl);
|
||||
}
|
||||
return tooltipEl;
|
||||
}
|
||||
|
|
@ -59,8 +59,8 @@ export class TooltipManager {
|
|||
});
|
||||
|
||||
// Global event listeners
|
||||
plugin.registerDomEvent(document, 'visibilitychange', () => {
|
||||
if (document.hidden) TooltipManager.forceHide();
|
||||
plugin.registerDomEvent(activeDocument, 'visibilitychange', () => {
|
||||
if (activeDocument.hidden) TooltipManager.forceHide();
|
||||
});
|
||||
|
||||
plugin.registerDomEvent(window, 'resize', () => {
|
||||
|
|
@ -93,7 +93,7 @@ export class TooltipManager {
|
|||
TooltipManager.forceHide();
|
||||
});
|
||||
|
||||
const root = document.querySelector('.workspace') || document.body;
|
||||
const root = activeDocument.querySelector('.workspace') || activeDocument.body;
|
||||
mutationObserver.observe(root, { childList: true, subtree: true });
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ export class TooltipManager {
|
|||
el.classList.add('macro-tooltip-mobile');
|
||||
|
||||
// Position near the bottom of the Obsidian app, but above the toolbar
|
||||
const obsidianApp = document.querySelector('.app-container') || document.body;
|
||||
const obsidianApp = activeDocument.querySelector('.app-container') || activeDocument.body;
|
||||
const appRect = obsidianApp.getBoundingClientRect();
|
||||
|
||||
// Set Y position to be above the bottom toolbar (more clearance)
|
||||
|
|
|
|||
Loading…
Reference in a new issue