mirror of
https://github.com/scotttomaszewski/obsidian-disciples-journal.git
synced 2026-07-22 05:42:13 +00:00
Satisfies code reviews and supports popout windows
This commit is contained in:
parent
6ede491e94
commit
43ebec00eb
7 changed files with 62 additions and 83 deletions
|
|
@ -128,7 +128,7 @@ export class BibleReferenceRenderer {
|
|||
}
|
||||
|
||||
// Create a Bible reference element
|
||||
const referenceEl = document.createElement('span');
|
||||
const referenceEl = element.doc.createElement('span');
|
||||
referenceEl.classList.add('bible-reference');
|
||||
referenceEl.textContent = codeText;
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ export class BibleReferenceRenderer {
|
|||
const passage = await this.bibleContentService.getBibleContent(reference);
|
||||
|
||||
if (passage) {
|
||||
const containerEl = document.createElement('div');
|
||||
const containerEl = el.doc.createElement('div');
|
||||
containerEl.classList.add('bible-passage-container');
|
||||
|
||||
const parsedRef = this.parser.parse(reference);
|
||||
|
|
@ -186,7 +186,7 @@ export class BibleReferenceRenderer {
|
|||
// }
|
||||
|
||||
// Add reference heading
|
||||
const headingEl = document.createElement('h3');
|
||||
const headingEl = el.doc.createElement('h3');
|
||||
headingEl.classList.add('bible-passage-heading');
|
||||
const referenceLink = headingEl.createEl('a', { text: passage.reference });
|
||||
referenceLink.onClickEvent(async l => {
|
||||
|
|
@ -196,7 +196,7 @@ export class BibleReferenceRenderer {
|
|||
containerEl.appendChild(headingEl);
|
||||
|
||||
// Add verses
|
||||
const passageEl = document.createElement('div');
|
||||
const passageEl = el.doc.createElement('div');
|
||||
passageEl.classList.add('bible-passage-text');
|
||||
|
||||
// Check if we have HTML content
|
||||
|
|
@ -206,14 +206,14 @@ export class BibleReferenceRenderer {
|
|||
} else {
|
||||
// Fallback to traditional verse rendering
|
||||
for (const verse of passage.verses) {
|
||||
const verseEl = document.createElement('p');
|
||||
const verseEl = el.doc.createElement('p');
|
||||
verseEl.classList.add('bible-verse');
|
||||
|
||||
const verseNumEl = document.createElement('span');
|
||||
const verseNumEl = el.doc.createElement('span');
|
||||
verseNumEl.classList.add('bible-verse-number');
|
||||
verseNumEl.textContent = `${verse.verse} `;
|
||||
|
||||
const verseTextEl = document.createElement('span');
|
||||
const verseTextEl = el.doc.createElement('span');
|
||||
verseTextEl.classList.add('bible-verse-text');
|
||||
verseTextEl.textContent = verse.text;
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ export class BibleReferenceRenderer {
|
|||
el.appendChild(containerEl);
|
||||
} else {
|
||||
// If reference not found, show error
|
||||
const errorEl = document.createElement('div');
|
||||
const errorEl = el.doc.createElement('div');
|
||||
errorEl.classList.add('bible-reference-error');
|
||||
errorEl.textContent = `Bible reference "${reference}" not found.`;
|
||||
el.appendChild(errorEl);
|
||||
|
|
@ -243,11 +243,11 @@ export class BibleReferenceRenderer {
|
|||
if (!passage) return null;
|
||||
|
||||
// Create verse preview element
|
||||
const versePreviewEl = document.createElement('div');
|
||||
const versePreviewEl = element.doc.createElement('div');
|
||||
versePreviewEl.classList.add('bible-verse-preview');
|
||||
|
||||
// Add reference heading (make it clickable)
|
||||
const headingEl = document.createElement('div');
|
||||
const headingEl = element.doc.createElement('div');
|
||||
headingEl.classList.add('bible-verse-preview-heading', 'bible-reference-clickable');
|
||||
headingEl.textContent = passage.reference;
|
||||
|
||||
|
|
@ -263,7 +263,7 @@ export class BibleReferenceRenderer {
|
|||
|
||||
// Close the preview - using a method available in BibleEventHandlers
|
||||
// Remove the popup directly instead of trying to access the private property
|
||||
const previewPoppers = document.querySelectorAll('.bible-verse-preview');
|
||||
const previewPoppers = element.doc.querySelectorAll('.bible-verse-preview');
|
||||
if (previewPoppers) {
|
||||
previewPoppers.forEach(p => p.remove());
|
||||
}
|
||||
|
|
@ -278,7 +278,7 @@ export class BibleReferenceRenderer {
|
|||
versePreviewEl.appendChild(headingEl);
|
||||
|
||||
// Add verse content
|
||||
const contentEl = document.createElement('div');
|
||||
const contentEl = element.doc.createElement('div');
|
||||
contentEl.classList.add('bible-verse-preview-content');
|
||||
|
||||
// Check if we have HTML content
|
||||
|
|
@ -287,7 +287,7 @@ export class BibleReferenceRenderer {
|
|||
// for the preview (to avoid showing footnotes, chapter headings, etc.)
|
||||
try {
|
||||
// Create a temporary element to parse the HTML
|
||||
const tempEl = document.createElement('div');
|
||||
const tempEl = element.doc.createElement('div');
|
||||
tempEl.innerHTML = passage.htmlContent;
|
||||
|
||||
// Find and extract the main verse content (paragraphs)
|
||||
|
|
@ -307,16 +307,16 @@ export class BibleReferenceRenderer {
|
|||
} else {
|
||||
// Fallback to traditional verse rendering
|
||||
for (const verse of passage.verses) {
|
||||
const verseEl = document.createElement('p');
|
||||
const verseEl = element.doc.createElement('p');
|
||||
|
||||
if (passage.verses.length > 1) {
|
||||
const verseNumEl = document.createElement('span');
|
||||
const verseNumEl = element.doc.createElement('span');
|
||||
verseNumEl.classList.add('bible-verse-number');
|
||||
verseNumEl.textContent = `${verse.verse} `;
|
||||
verseEl.appendChild(verseNumEl);
|
||||
}
|
||||
|
||||
const verseTextEl = document.createElement('span');
|
||||
const verseTextEl = element.doc.createElement('span');
|
||||
verseTextEl.textContent = verse.text;
|
||||
verseEl.appendChild(verseTextEl);
|
||||
|
||||
|
|
@ -335,7 +335,7 @@ export class BibleReferenceRenderer {
|
|||
versePreviewEl.style.top = `${rect.bottom - 3}px`;
|
||||
|
||||
// Add popup to document
|
||||
document.body.appendChild(versePreviewEl);
|
||||
element.doc.body.appendChild(versePreviewEl);
|
||||
|
||||
return versePreviewEl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ export class BibleStyles {
|
|||
/**
|
||||
* Apply styles by updating CSS variables based on theme, preset, and settings.
|
||||
*/
|
||||
public applyStyles(theme: 'light' | 'dark', presetName: string = 'default', fontSize: string = '100%', settings?: {
|
||||
public applyStyles(doc: Document, theme: 'light' | 'dark', presetName: string = 'default', fontSize: string = '100%', settings?: {
|
||||
wordsOfChristColor?: string;
|
||||
verseNumberColor?: string;
|
||||
headingColor?: string;
|
||||
|
|
@ -115,7 +115,7 @@ export class BibleStyles {
|
|||
}
|
||||
|
||||
// Update the CSS variables on the root element
|
||||
const rootStyle = document.documentElement.style;
|
||||
const rootStyle = doc.body.style;
|
||||
rootStyle.setProperty('--dj-font-size', options.fontSize);
|
||||
rootStyle.setProperty('--dj-heading-color', options.headingColor);
|
||||
rootStyle.setProperty('--dj-verse-number-color', options.verseNumberColor);
|
||||
|
|
@ -127,8 +127,8 @@ export class BibleStyles {
|
|||
* Resets the custom styles potentially set by this class by removing the CSS variables.
|
||||
* This allows the default styles in styles.css to take effect.
|
||||
*/
|
||||
public resetStyles(): void {
|
||||
const rootStyle = document.documentElement.style;
|
||||
public resetStyles(doc: Document): void {
|
||||
const rootStyle = doc.body.style;
|
||||
rootStyle.removeProperty('--dj-font-size');
|
||||
rootStyle.removeProperty('--dj-heading-color');
|
||||
rootStyle.removeProperty('--dj-verse-number-color');
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ export class BibleEventHandlers {
|
|||
!relatedTarget.classList.contains('bible-reference') &&
|
||||
!relatedTarget.closest('.bible-verse-preview')) {
|
||||
this.previewPopper?.classList.remove('popup-locked');
|
||||
this.removePreviewPopper();
|
||||
this.removePreviewPopper(relatedTarget.doc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -125,7 +125,7 @@ export class BibleEventHandlers {
|
|||
if (!this.previewPopper || this.previewPopper.classList.contains('popup-locked')) {
|
||||
return;
|
||||
}
|
||||
this.removePreviewPopper();
|
||||
this.removePreviewPopper(relatedTarget.doc);
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
|
|
@ -163,20 +163,20 @@ export class BibleEventHandlers {
|
|||
}
|
||||
|
||||
// In all other cases, remove the popup
|
||||
this.removePreviewPopper();
|
||||
this.removePreviewPopper(target.doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the preview popper if it exists
|
||||
*/
|
||||
removePreviewPopper() {
|
||||
removePreviewPopper(doc: Document) {
|
||||
if (this.previewPopper) {
|
||||
// Remove any hover gap elements
|
||||
const hoverGaps = document.querySelectorAll('.bible-hover-gap');
|
||||
const hoverGaps = doc.querySelectorAll('.bible-hover-gap');
|
||||
hoverGaps.forEach(gap => gap.remove());
|
||||
|
||||
this.previewPopper.remove();
|
||||
this.previewPopper = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,8 +8,8 @@ import { BibleReferenceRenderer } from '../components/BibleReferenceRenderer';
|
|||
import { BibleStyles } from '../components/BibleStyles';
|
||||
import { DisciplesJournalSettings, DEFAULT_SETTINGS, DisciplesJournalSettingsTab } from '../settings/DisciplesJournalSettings';
|
||||
import { BibleFormatter } from "../utils/BibleFormatter";
|
||||
import { NoteCreationService } from 'src/services/NoteCreationService';
|
||||
import { BibleEventHandlers } from './BibleEventHandlers';
|
||||
import { NoteCreationService } from '../services/NoteCreationService';
|
||||
import { BibleMarkupProcessor } from './BibleMarkupProcessor';
|
||||
|
||||
/**
|
||||
|
|
@ -62,7 +62,7 @@ export default class DisciplesJournalPlugin extends Plugin {
|
|||
|
||||
// Initialize components
|
||||
this.bibleReferenceParser = new BibleReferenceParser(this.bookNameService);
|
||||
this.bibleStyles = new BibleStyles(this.settings.bibleTextFontSize);
|
||||
this.bibleStyles = new BibleStyles();
|
||||
this.bibleReferenceRenderer = new BibleReferenceRenderer(
|
||||
this.app,
|
||||
this.bibleContentService,
|
||||
|
|
@ -118,8 +118,6 @@ export default class DisciplesJournalPlugin extends Plugin {
|
|||
}
|
||||
|
||||
onunload() {
|
||||
console.log('Unloading Disciples Journal plugin');
|
||||
this.bibleStyles.removeStyles();
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
|
|
@ -167,47 +165,25 @@ export default class DisciplesJournalPlugin extends Plugin {
|
|||
const activeLeaf = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
if (!activeLeaf) return;
|
||||
|
||||
const isDarkMode = document.body.classList.contains('theme-dark');
|
||||
const theme = isDarkMode ? 'dark' : 'light';
|
||||
|
||||
// Pass custom settings from DisciplesJournalSettings
|
||||
this.bibleStyles.applyStyles(
|
||||
theme,
|
||||
this.settings.stylePreset,
|
||||
this.settings.bibleTextFontSize,
|
||||
{
|
||||
wordsOfChristColor: this.settings.wordsOfChristColor,
|
||||
verseNumberColor: this.settings.verseNumberColor,
|
||||
headingColor: this.settings.headingColor,
|
||||
blockIndentation: this.settings.blockIndentation
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update font size for Bible verses (legacy method for compatibility)
|
||||
*/
|
||||
public updateFontSize(fontSize: string): void {
|
||||
this.bibleStyles.setFontSize(fontSize);
|
||||
|
||||
// Refresh the styles with the new font size and current settings
|
||||
const isDarkMode = document.body.classList.contains('theme-dark');
|
||||
const theme = isDarkMode ? 'dark' : 'light';
|
||||
|
||||
// Apply styles with the new font size and current settings
|
||||
this.bibleStyles.applyStyles(
|
||||
theme,
|
||||
this.settings.stylePreset,
|
||||
fontSize,
|
||||
{
|
||||
wordsOfChristColor: this.settings.wordsOfChristColor,
|
||||
verseNumberColor: this.settings.verseNumberColor,
|
||||
headingColor: this.settings.headingColor,
|
||||
blockIndentation: this.settings.blockIndentation
|
||||
}
|
||||
);
|
||||
|
||||
this.bibleReferenceRenderer.setFontSize(fontSize);
|
||||
// Each popup window has a unique document, so we need to apply styles to each one
|
||||
const docList: Document[] = [];
|
||||
this.app.workspace.iterateAllLeaves(leaf => docList.push(leaf.getContainer().doc));
|
||||
docList.unique().forEach(doc => {
|
||||
const isDarkMode = activeLeaf.containerEl.doc.body.classList.contains('theme-dark');
|
||||
const theme = isDarkMode ? 'dark' : 'light';
|
||||
this.bibleStyles.applyStyles(
|
||||
doc,
|
||||
theme,
|
||||
this.settings.stylePreset,
|
||||
this.settings.bibleTextFontSize,
|
||||
{
|
||||
wordsOfChristColor: this.settings.wordsOfChristColor,
|
||||
verseNumberColor: this.settings.verseNumberColor,
|
||||
headingColor: this.settings.headingColor,
|
||||
blockIndentation: this.settings.blockIndentation
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -161,42 +161,42 @@ export class ESVApiService {
|
|||
/**
|
||||
* Create a DOM-friendly error message for missing token or API errors
|
||||
*/
|
||||
private createErrorMessageContent(type: 'missing-token' | 'api-error', message: string = '', details: string = ''): HTMLElement {
|
||||
private createErrorMessageContent(doc: Document, type: 'missing-token' | 'api-error', message: string = '', details: string = ''): HTMLElement {
|
||||
// We're required to return a string here because it's part of the ESV API response structure
|
||||
// This method creates the content in a DOM-safe way then serializes to a string
|
||||
const container = document.createElement('div');
|
||||
const container = doc.createElement('div');
|
||||
container.className = type === 'missing-token' ? 'bible-missing-token-warning' : 'bible-api-error';
|
||||
|
||||
const titleEl = document.createElement('p');
|
||||
const titleStrong = document.createElement('strong');
|
||||
const titleEl = doc.createElement('p');
|
||||
const titleStrong = doc.createElement('strong');
|
||||
titleStrong.textContent = type === 'missing-token' ? 'ESV API Token Not Set' : 'Error Loading Bible Passage';
|
||||
titleEl.appendChild(titleStrong);
|
||||
container.appendChild(titleEl);
|
||||
|
||||
if (message) {
|
||||
const messageEl = document.createElement('p');
|
||||
const messageEl = doc.createElement('p');
|
||||
messageEl.textContent = message;
|
||||
container.appendChild(messageEl);
|
||||
}
|
||||
|
||||
if (details) {
|
||||
const detailsEl = document.createElement('p');
|
||||
const detailsEl = doc.createElement('p');
|
||||
detailsEl.textContent = details;
|
||||
container.appendChild(detailsEl);
|
||||
}
|
||||
|
||||
// For the API token link
|
||||
if (type === 'missing-token') {
|
||||
const linkPara = document.createElement('p');
|
||||
const linkPara = doc.createElement('p');
|
||||
linkPara.textContent = 'You can request a free token from ';
|
||||
|
||||
const link = document.createElement('a');
|
||||
const link = doc.createElement('a');
|
||||
link.textContent = 'api.esv.org';
|
||||
link.href = 'https://api.esv.org/docs/';
|
||||
link.target = '_blank';
|
||||
|
||||
linkPara.appendChild(link);
|
||||
linkPara.appendChild(document.createTextNode('.'));
|
||||
linkPara.appendChild(doc.createTextNode('.'));
|
||||
container.appendChild(linkPara);
|
||||
}
|
||||
|
||||
|
|
@ -214,6 +214,7 @@ export class ESVApiService {
|
|||
reference: reference,
|
||||
verses: [],
|
||||
htmlContent: this.createErrorMessageContent(
|
||||
document,
|
||||
'missing-token',
|
||||
'To display Bible passages, you need to set up an ESV API token in the plugin settings.'
|
||||
).outerHTML,
|
||||
|
|
@ -257,6 +258,7 @@ export class ESVApiService {
|
|||
reference: reference,
|
||||
verses: [],
|
||||
htmlContent: this.createErrorMessageContent(
|
||||
document,
|
||||
'api-error',
|
||||
'Failed to load the passage from the ESV API.',
|
||||
`Status: ${response.status}. Please check your API token in the plugin settings.`
|
||||
|
|
@ -270,6 +272,7 @@ export class ESVApiService {
|
|||
reference: reference,
|
||||
verses: [],
|
||||
htmlContent: this.createErrorMessageContent(
|
||||
document,
|
||||
'api-error',
|
||||
'An error occurred when trying to access the ESV API.',
|
||||
'Please check your internet connection and API token.'
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ export class NoteCreationService {
|
|||
if (parsedRef.verse) {
|
||||
setTimeout(() => {
|
||||
// Find the verse element and scroll to it
|
||||
const verseEl = document.querySelector(`.verse-${parsedRef.verse}`);
|
||||
const verseEl = leaf.getContainer().doc.querySelector(`.verse-${parsedRef.verse}`);
|
||||
if (verseEl) {
|
||||
verseEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ export class DisciplesJournalSettingsTab extends PluginSettingTab {
|
|||
.setValue(this.plugin.settings.bibleTextFontSize)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.bibleTextFontSize = value;
|
||||
this.plugin.updateFontSize(value);
|
||||
await this.plugin.saveSettings();
|
||||
this.plugin.updateBibleStyles();
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue