Refactors the code into easy object space.

This commit is contained in:
Llewellyn van der Merwe 2023-12-04 09:23:23 +02:00
parent 0fdb273255
commit 1160b14bec
Signed by: Llewellyn
GPG Key ID: A9201372263741E7
26 changed files with 431 additions and 303 deletions

View File

@ -12,7 +12,7 @@ GetBible loader is an intuitive and lightweight JavaScript solution for embeddin
```html ```html
<!-- Include the GetBible tooltips script from jsDelivr CDN --> <!-- Include the GetBible tooltips script from jsDelivr CDN -->
<script src="https://cdn.jsdelivr.net/gh/getbible/loader@3.0.1/dist/js/getBible.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/getbible/loader@3.0.3/dist/js/getBible.min.js"></script>
``` ```
2. **Markup Your Scripture References:** 2. **Markup Your Scripture References:**

362
dist/js/getBible.js vendored
View File

@ -1,5 +1,5 @@
/** /**
* getBible Loader v3.0.2 * getBible Loader v3.0.3
* https://getbible.net * https://getbible.net
* (c) 2014 - 2023 Llewellyn van der Merwe * (c) 2014 - 2023 Llewellyn van der Merwe
* MIT License * MIT License
@ -155,8 +155,38 @@
* Initializes the BibleVerse object with verse data. * Initializes the BibleVerse object with verse data.
* *
* @param {Object} data - The JSON data containing verse information. * @param {Object} data - The JSON data containing verse information.
* @param {string} data.translation - The name of the translation.
* @param {string} data.abbreviation - The abbreviation of the translation.
* @param {string} data.language - The full language name.
* @param {string} data.lang - The language code.
* @param {string} data.direction - The text direction (LTR or RTL).
* @param {string} data.encoding - The encoding format (e.g., UTF-8).
* @param {number} data.book_nr - The book number.
* @param {string} data.book_name - The name of the book.
* @param {number} data.chapter - The chapter number.
* @param {string} data.name - The name of the chapter.
* @param {Array<Object>} data.verses - An array of objects representing each verse.
* @param {string|Array<string>} data.ref - The local reference string or array of strings.
*/ */
constructor(data) { constructor(data) {
// Simple validation to check if essential properties are present
const requiredProperties = [
'translation', 'abbreviation', 'language', 'lang',
'direction', 'encoding', 'book_nr', 'book_name',
'chapter', 'name', 'verses', 'ref'
];
if (!data || typeof data !== 'object') {
throw new Error('Data must be a valid object.');
}
requiredProperties.forEach(prop => {
if (data[prop] === undefined || data[prop] === null) {
throw new Error(`Missing required property: '${prop}'.`);
}
});
// Assign the data after validation
this.#data = data; this.#data = data;
} }
@ -165,7 +195,7 @@
* *
* @returns {string} The name of the translation. * @returns {string} The name of the translation.
*/ */
getTranslation() { get translation() {
return this.#data.translation; return this.#data.translation;
} }
@ -174,26 +204,26 @@
* *
* @returns {string} The abbreviation of the translation. * @returns {string} The abbreviation of the translation.
*/ */
getAbbreviation() { get abbreviation() {
return this.#data.abbreviation; return this.#data.abbreviation;
} }
/**
* Retrieves the language code.
*
* @returns {string} The language code.
*/
getLanguage() {
return this.#data.lang;
}
/** /**
* Retrieves the full language name. * Retrieves the full language name.
* *
* @returns {string} The language code.
*/
get language() {
return this.#data.language;
}
/**
* Retrieves the language code.
*
* @returns {string} The full name of the language. * @returns {string} The full name of the language.
*/ */
getLanguageName() { get languageCode() {
return this.#data.language; return this.#data.lang;
} }
/** /**
@ -201,7 +231,7 @@
* *
* @returns {string} The direction of the text (LTR or RTL). * @returns {string} The direction of the text (LTR or RTL).
*/ */
getTextDirection() { get textDirection() {
return this.#data.direction; return this.#data.direction;
} }
@ -210,7 +240,7 @@
* *
* @returns {string} The encoding format (e.g., UTF-8). * @returns {string} The encoding format (e.g., UTF-8).
*/ */
getEncoding() { get encoding() {
return this.#data.encoding; return this.#data.encoding;
} }
@ -219,7 +249,7 @@
* *
* @returns {number} The book number. * @returns {number} The book number.
*/ */
getBookNumber() { get bookNumber() {
return this.#data.book_nr; return this.#data.book_nr;
} }
@ -228,7 +258,7 @@
* *
* @returns {string} The name of the book. * @returns {string} The name of the book.
*/ */
getBookName() { get bookName() {
return this.#data.book_name; return this.#data.book_name;
} }
@ -237,7 +267,7 @@
* *
* @returns {number} The chapter number. * @returns {number} The chapter number.
*/ */
getChapter() { get chapter() {
return this.#data.chapter; return this.#data.chapter;
} }
@ -246,16 +276,17 @@
* *
* @returns {string} The name of the chapter. * @returns {string} The name of the chapter.
*/ */
getChapterName() { get chapterName() {
return this.#data.name; return this.#data.name;
} }
/** /**
* Retrieves all verses of the chapter. * Retrieves all verses of the chapter.
* *
* @returns {Array<Object>} An array of objects representing each verse. * @returns {Array<{chapter: number, verse: number, name: string, text: string}>}
* An array of objects representing each verse.
*/ */
getVerses() { get verses() {
return this.#data.verses; return this.#data.verses;
} }
@ -280,12 +311,22 @@
return this.#data.verses.filter(verse => verse.verse >= startVerse && verse.verse <= endVerse); return this.#data.verses.filter(verse => verse.verse >= startVerse && verse.verse <= endVerse);
} }
/**
* Get the local reference string set in the website.
*
* @returns {string} The reference string.
*/
get localReference() {
// Ensure that this.#data.ref is treated as an array.
return Array.isArray(this.#data.ref) ? this.#data.ref.join('; ') : this.#data.ref;
}
/** /**
* Generates a reference string for the verses. * Generates a reference string for the verses.
* *
* @returns {string} The reference string. * @returns {string} The reference string.
*/ */
getReference() { get reference() {
const verseNumbers = this.#data.verses.map(verse => verse.verse).sort((a, b) => a - b); const verseNumbers = this.#data.verses.map(verse => verse.verse).sort((a, b) => a - b);
let refString = `${this.#data.name}:`; let refString = `${this.#data.name}:`;
let ranges = {}; let ranges = {};
@ -331,26 +372,6 @@
this.#references = Object.values(data).map(reference => new Reference(reference)); this.#references = Object.values(data).map(reference => new Reference(reference));
} }
/**
* Gets a reference by its numerical index.
*
* @param {number} index - The index of the reference.
* @returns {Reference|null} The Reference instance or null if out of bounds.
*/
getReference(index) {
return (index >= 0 && index < this.#references.length) ? this.#references[index] : null;
}
/**
* Gets the translation.
*
* @param {number} index - The index of the reference.
* @returns {Reference|null} The Reference instance or null if out of bounds.
*/
getReference(index) {
return (index >= 0 && index < this.#references.length) ? this.#references[index] : null;
}
/** /**
* Iterates over all references and performs a callback function. * Iterates over all references and performs a callback function.
* *
@ -370,9 +391,11 @@
#translations; #translations;
#showBookName; #showBookName;
#showReference; #showReference;
#showLocalReference;
#showTranslation; #showTranslation;
#showAbbreviation; #showAbbreviation;
#showLanguage; #showLanguage;
#showLanguageCode;
/** /**
* Initializes the Actions object with a DOM element and its data attributes. * Initializes the Actions object with a DOM element and its data attributes.
@ -390,9 +413,15 @@
this.#translations = (element.dataset.translation || 'kjv').toLowerCase().split(';').map(translation => translation.trim()); this.#translations = (element.dataset.translation || 'kjv').toLowerCase().split(';').map(translation => translation.trim());
this.#showBookName = element.dataset.showBookName ? parseInt(element.dataset.showBookName, 10) : 0; this.#showBookName = element.dataset.showBookName ? parseInt(element.dataset.showBookName, 10) : 0;
this.#showReference = element.dataset.showReference ? parseInt(element.dataset.showReference, 10) : 1; this.#showReference = element.dataset.showReference ? parseInt(element.dataset.showReference, 10) : 1;
this.#showLocalReference = element.dataset.showLocalReference ? parseInt(element.dataset.showLocalReference, 10) : 0;
this.#showTranslation = element.dataset.showTranslation ? parseInt(element.dataset.showTranslation, 10) : 0; this.#showTranslation = element.dataset.showTranslation ? parseInt(element.dataset.showTranslation, 10) : 0;
this.#showAbbreviation = element.dataset.showAbbreviation ? parseInt(element.dataset.showAbbreviation, 10) : 0; this.#showAbbreviation = element.dataset.showAbbreviation ? parseInt(element.dataset.showAbbreviation, 10) : 0;
this.#showLanguage = element.dataset.showLanguage ? parseInt(element.dataset.showLanguage, 10) : 0; this.#showLanguage = element.dataset.showLanguage ? parseInt(element.dataset.showLanguage, 10) : 0;
this.#showLanguageCode = element.dataset.showLanguageCode ? parseInt(element.dataset.showLanguageCode, 10) : 0;
if (this.#showLocalReference){
this.#showReference = 0;
}
} }
/** /**
@ -400,7 +429,7 @@
* *
* @returns {Array<string>} An array of translation strings. * @returns {Array<string>} An array of translation strings.
*/ */
getTranslations() { get translations() {
return this.#translations; return this.#translations;
} }
@ -409,7 +438,7 @@
* *
* @returns {number} The show book name flag (0 or 1). * @returns {number} The show book name flag (0 or 1).
*/ */
showBookName() { get bookName() {
return this.#showBookName; return this.#showBookName;
} }
@ -418,16 +447,25 @@
* *
* @returns {number} The show reference flag (0 or 1). * @returns {number} The show reference flag (0 or 1).
*/ */
showReference() { get reference() {
return this.#showReference; return this.#showReference;
} }
/**
* Retrieves the show local reference flag.
*
* @returns {number} The show reference flag (0 or 1).
*/
get localReference() {
return this.#showLocalReference;
}
/** /**
* Retrieves the show translation flag. * Retrieves the show translation flag.
* *
* @returns {number} The show translation flag (0 or 1). * @returns {number} The show translation flag (0 or 1).
*/ */
showTranslation() { get translation() {
return this.#showTranslation; return this.#showTranslation;
} }
@ -436,7 +474,7 @@
* *
* @returns {number} The show abbreviation flag (0 or 1). * @returns {number} The show abbreviation flag (0 or 1).
*/ */
showAbbreviation() { get abbreviation() {
return this.#showAbbreviation; return this.#showAbbreviation;
} }
@ -445,16 +483,25 @@
* *
* @returns {number} The show language flag (0 or 1). * @returns {number} The show language flag (0 or 1).
*/ */
showLanguage() { get language() {
return this.#showLanguage; return this.#showLanguage;
} }
/**
* Retrieves the show language code flog.
*
* @returns {number} The show language flag (0 or 1).
*/
get languageCode() {
return this.#showLanguageCode;
}
/** /**
* Retrieves the element format. * Retrieves the element format.
* *
* @returns {string} The element format. * @returns {string} The element format.
*/ */
getFormat() { get format() {
return this.#format; return this.#format;
} }
@ -463,7 +510,7 @@
* *
* @returns {HTMLElement} The DOM element associated with this object. * @returns {HTMLElement} The DOM element associated with this object.
*/ */
getElement() { get element() {
return this.#element; return this.#element;
} }
} }
@ -485,7 +532,7 @@
* *
* @returns {Action} The current actions. * @returns {Action} The current actions.
*/ */
action() { get action() {
return this.#action; return this.#action;
} }
@ -516,27 +563,33 @@
let display = []; let display = [];
scripture.forEachReference((reference) => { scripture.forEachReference((reference) => {
let header = []; let header = [];
display.push(`<div dir="${reference.getTextDirection().toUpperCase()}" class="getbible-reference-block">`); display.push(`<div dir="${reference.textDirection.toUpperCase()}" class="getbible-reference-block">`);
if (this.action().showBookName()) { if (this.action.bookName) {
header.push(`<span class="getbible-book-name">${reference.getBookName()}</span>`); header.push(`<span class="getbible-book-name">${reference.bookName}</span>`);
} }
if (this.action().showReference()) { if (this.action.reference) {
header.push(`<span class="getbible-reference">${reference.getReference()}</span>`); header.push(`<span class="getbible-reference">${reference.reference}</span>`);
} }
if (this.action().showTranslation()) { if (this.action.localReference) {
header.push(`<span class="getbible-translation">${reference.getTranslation()}</span>`); header.push(`<span class="getbible-reference">${reference.localReference}</span>`);
} }
if (this.action().showAbbreviation()) { if (this.action.translation) {
header.push(`<span class="getbible-abbreviation">${reference.getAbbreviation()}</span>`); header.push(`<span class="getbible-translation">${reference.translation}</span>`);
} }
if (this.action().showLanguage()) { if (this.action.abbreviation) {
header.push(`<span class="getbible-language">${reference.getLanguage()}</span>`); header.push(`<span class="getbible-abbreviation">${reference.abbreviation}</span>`);
}
if (this.action.language) {
header.push(`<span class="getbible-language">${reference.language}</span>`);
}
if (this.action.languageCode) {
header.push(`<span class="getbible-language-code">${reference.languageCode}</span>`);
} }
// Construct the header // Construct the header
if (header.length > 0) { if (header.length > 0) {
display.push(`<b class="getbible-header">${header.join(' - ')}</b>`); display.push(`<b class="getbible-header">${header.join(' - ')}</b>`);
} }
const verses = reference.getVerses() const verses = reference.verses
.map(verse => `<div class="getbible-verse">${verse.verse}. ${verse.text}</div>`) .map(verse => `<div class="getbible-verse">${verse.verse}. ${verse.text}</div>`)
.join("\n"); .join("\n");
display.push(`<div class="getbible-verses">${verses}</div>`); display.push(`<div class="getbible-verses">${verses}</div>`);
@ -562,23 +615,29 @@
let display = []; let display = [];
scripture.forEachReference((reference) => { scripture.forEachReference((reference) => {
let footer = []; let footer = [];
display.push(`<div dir="${reference.getTextDirection().toUpperCase()}" class="getbible-reference-inline">`); display.push(`<div dir="${reference.textDirection.toUpperCase()}" class="getbible-reference-inline">`);
if (this.action().showBookName()) { if (this.action.bookName) {
footer.push(`<span class="getbible-book-name">${reference.getBookName()}</span>`); footer.push(`<span class="getbible-book-name">${reference.bookName}</span>`);
} }
if (this.action().showReference()) { if (this.action.reference) {
footer.push(`<span class="getbible-reference">${reference.getReference()}</span>`); footer.push(`<span class="getbible-reference">${reference.reference}</span>`);
} }
if (this.action().showTranslation()) { if (this.action.localReference) {
footer.push(`<span class="getbible-translation">${reference.getTranslation()}</span>`); footer.push(`<span class="getbible-reference">${reference.localReference}</span>`);
} }
if (this.action().showAbbreviation()) { if (this.action.translation) {
footer.push(`<span class="getbible-abbreviation">${reference.getAbbreviation()}</span>`); footer.push(`<span class="getbible-translation">${reference.translation}</span>`);
} }
if (this.action().showLanguage()) { if (this.action.abbreviation) {
footer.push(`<span class="getbible-language">${reference.getLanguage()}</span>`); footer.push(`<span class="getbible-abbreviation">${reference.abbreviation}</span>`);
} }
const verses = reference.getVerses() if (this.action.language) {
footer.push(`<span class="getbible-language">${reference.language}</span>`);
}
if (this.action.languageCode) {
footer.push(`<span class="getbible-language-code">${reference.languageCode}</span>`);
}
const verses = reference.verses
.map(verse => `<span class="getbible-verse">${verse.verse}. ${verse.text}</span>`) .map(verse => `<span class="getbible-verse">${verse.verse}. ${verse.text}</span>`)
.join("\n"); .join("\n");
display.push(`<span class="getbible-verses">${verses}</span>`); display.push(`<span class="getbible-verses">${verses}</span>`);
@ -608,27 +667,33 @@
let display = []; let display = [];
scripture.forEachReference((reference) => { scripture.forEachReference((reference) => {
let header = []; let header = [];
if (this.action().showBookName()) { if (this.action.bookName) {
header.push(`${reference.getBookName()}`); header.push(`${reference.bookName}`);
} }
if (this.action().showReference()) { if (this.action.reference) {
header.push(`${reference.getReference()}`); header.push(`${reference.reference}`);
} }
if (this.action().showTranslation()) { if (this.action.localReference) {
header.push(`${reference.getTranslation()}`); header.push(`${reference.localReference}`);
} }
if (this.action().showAbbreviation()) { if (this.action.translation) {
header.push(`${reference.getAbbreviation()}`); header.push(`${reference.translation}`);
} }
if (this.action().showLanguage()) { if (this.action.abbreviation) {
header.push(`${reference.getLanguage()}`); header.push(`${reference.abbreviation}`);
}
if (this.action.language) {
header.push(`${reference.language}`);
}
if (this.action.languageCode) {
header.push(`${reference.languageCode}`);
} }
// Construct the header // Construct the header
if (header.length > 0) { if (header.length > 0) {
display.push(`[${header.join(' - ')}]`); display.push(`[${header.join(' - ')}]`);
} }
display.push( display.push(
reference.getVerses() reference.verses
.map(verse => `${verse.verse}. ${verse.text}`) .map(verse => `${verse.verse}. ${verse.text}`)
.join("\n") .join("\n")
); );
@ -655,7 +720,7 @@
'tooltip': PlainFormat 'tooltip': PlainFormat
}; };
const format = action.getFormat(); const format = action.format;
const FormatType = formatTypes[format] || InlineFormat; const FormatType = formatTypes[format] || InlineFormat;
this.format = new FormatType(action); this.format = new FormatType(action);
} }
@ -683,7 +748,7 @@
constructor(action) { constructor(action) {
this.#modalId = `modal-${Math.random().toString(36).slice(2, 11)}`; this.#modalId = `modal-${Math.random().toString(36).slice(2, 11)}`;
this.#action = action; this.#action = action;
this.getElement().style.cursor = 'pointer'; this.element.style.cursor = 'pointer';
this.initializeTrigger(); this.initializeTrigger();
} }
@ -693,11 +758,11 @@
* @param {string} content - The content to load into the modal. * @param {string} content - The content to load into the modal.
*/ */
load(content) { load(content) {
const existingModal = document.getElementById(this.getModalId()); const existingModal = document.getElementById(this.id);
// Check if modal already exists // Check if modal already exists
if (existingModal) { if (existingModal) {
// Update the content of the existing modal // Update the content of the existing modal
const contentDiv = document.getElementById(`${this.getModalId()}-content`); const contentDiv = document.getElementById(`${this.id}-content`);
if (contentDiv) { if (contentDiv) {
contentDiv.innerHTML += content; contentDiv.innerHTML += content;
} }
@ -723,17 +788,17 @@
*/ */
create(content) { create(content) {
const modalHtml = ` const modalHtml = `
<div id="${this.getModalId()}" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background-color:rgba(0, 0, 0, 0.5); justify-content:center; align-items:center;"> <div id="${this.id}" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background-color:rgba(0, 0, 0, 0.5); justify-content:center; align-items:center;">
<div style="position:relative; background-color:white; padding:20px; border-radius:5px; max-width:300px;"> <div style="position:relative; background-color:white; padding:20px; border-radius:5px; max-width:300px;">
<button class="getbible-modal-close" type="button" onclick="document.getElementById('${this.getModalId()}').style.display='none'" style="position:absolute; top:7px; right:7px; border:none; background:transparent; font-size:20px; cursor:pointer;"></button> <button class="getbible-modal-close" type="button" onclick="document.getElementById('${this.id}').style.display='none'" style="position:absolute; top:7px; right:7px; border:none; background:transparent; font-size:20px; cursor:pointer;"></button>
<div id="${this.getModalId()}-content"> <div id="${this.id}-content">
${content} ${content}
</div> </div>
</div> </div>
</div>`; </div>`;
this.insertIntoDOM(modalHtml); this.insertIntoDOM(modalHtml);
const modalElement = document.getElementById(this.getModalId()); const modalElement = document.getElementById(this.id);
modalElement.addEventListener('click', (event) => { modalElement.addEventListener('click', (event) => {
if (event.target === modalElement) { if (event.target === modalElement) {
modalElement.style.display = 'none'; modalElement.style.display = 'none';
@ -746,8 +811,8 @@
* *
*/ */
initializeTrigger() { initializeTrigger() {
this.getElement().addEventListener('click', () => { this.element.addEventListener('click', () => {
document.getElementById(this.getModalId()).style.display = 'flex'; document.getElementById(this.id).style.display = 'flex';
}); });
} }
@ -756,7 +821,7 @@
* *
* @returns {string} - The modal ID * @returns {string} - The modal ID
*/ */
getModalId() { get id() {
return this.#modalId; return this.#modalId;
} }
@ -765,8 +830,8 @@
* *
* @returns {HTMLElement} - The DOM element being worked with. * @returns {HTMLElement} - The DOM element being worked with.
*/ */
getElement() { get element() {
return this.#action.getElement(); return this.#action.element;
} }
} }
@ -776,19 +841,19 @@
} }
show() { show() {
UIkit.modal(`#${this.getModalId()}`).show(); UIkit.modal(`#${this.id}`).show();
} }
hide() { hide() {
UIkit.modal(`#${this.getModalId()}`).hide(); UIkit.modal(`#${this.id}`).hide();
} }
create(content) { create(content) {
const modalHtml = ` const modalHtml = `
<div id="${this.getModalId()}" uk-modal> <div id="${this.id}" uk-modal>
<div class="uk-modal-dialog uk-modal-body"> <div class="uk-modal-dialog uk-modal-body">
<button class="uk-modal-close-default" type="button" uk-close></button> <button class="uk-modal-close-default" type="button" uk-close></button>
<div id="${this.getModalId()}-content"> <div id="${this.id}-content">
${content} ${content}
</div> </div>
</div> </div>
@ -797,7 +862,7 @@
} }
initializeTrigger() { initializeTrigger() {
this.getElement().setAttribute('uk-toggle', `target: #${this.getModalId()}`); this.element.setAttribute('uk-toggle', `target: #${this.id}`);
} }
} }
@ -807,12 +872,12 @@
} }
show() { show() {
const modal = new bootstrap.Modal(document.getElementById(this.getModalId())); const modal = new bootstrap.Modal(document.getElementById(this.id));
modal.show(); modal.show();
} }
hide() { hide() {
const modal = bootstrap.Modal.getInstance(document.getElementById(this.getModalId())); const modal = bootstrap.Modal.getInstance(document.getElementById(this.id));
if (modal) { if (modal) {
modal.hide(); modal.hide();
} }
@ -820,13 +885,13 @@
create(content) { create(content) {
const modalHtml = ` const modalHtml = `
<div class="modal fade" id="${this.getModalId()}" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal fade" id="${this.id}" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content p-3"> <div class="modal-content p-3">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div id="${this.getModalId()}-content" class="modal-body"> <div id="${this.id}-content" class="modal-body">
${content} ${content}
</div> </div>
</div> </div>
@ -836,8 +901,8 @@
} }
initializeTrigger() { initializeTrigger() {
this.getElement().setAttribute('data-bs-toggle', 'modal'); this.element.setAttribute('data-bs-toggle', 'modal');
this.getElement().setAttribute('data-bs-target', `#${this.getModalId()}`); this.element.setAttribute('data-bs-target', `#${this.id}`);
} }
} }
@ -861,8 +926,8 @@
create(content) { create(content) {
const modalHtml = ` const modalHtml = `
<div class="reveal" id="${this.getModalId()}" data-reveal> <div class="reveal" id="${this.id}" data-reveal>
<div id="${this.getModalId()}-content"> <div id="${this.id}-content">
${content} ${content}
</div> </div>
<button class="close-button" data-close aria-label="Close modal" type="button"> <button class="close-button" data-close aria-label="Close modal" type="button">
@ -870,11 +935,11 @@
</button> </button>
</div>`; </div>`;
this.insertIntoDOM(modalHtml); this.insertIntoDOM(modalHtml);
this.modalElement = new Foundation.Reveal(document.getElementById(this.getModalId())); this.modalElement = new Foundation.Reveal(document.getElementById(this.id));
} }
initializeTrigger() { initializeTrigger() {
this.getElement().setAttribute('data-open', this.getModalId()); this.element.setAttribute('data-open', this.id);
} }
} }
@ -884,29 +949,29 @@
} }
show() { show() {
document.getElementById(this.getModalId()).classList.remove('hidden'); document.getElementById(this.id).classList.remove('hidden');
} }
hide() { hide() {
document.getElementById(this.getModalId()).classList.add('hidden'); document.getElementById(this.id).classList.add('hidden');
} }
create(content) { create(content) {
const modalHtml = ` const modalHtml = `
<div class="modal hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full" id="${this.getModalId()}"> <div class="modal hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full" id="${this.id}">
<div class="modal-content container mx-auto p-5 bg-white"> <div class="modal-content container mx-auto p-5 bg-white">
<div id="${this.getModalId()}-content"> <div id="${this.id}-content">
${content} ${content}
</div> </div>
<button class="close-button" onclick="document.getElementById('${this.getModalId()}').classList.add('hidden')">Close</button> <button class="close-button" onclick="document.getElementById('${this.id}').classList.add('hidden')">Close</button>
</div> </div>
</div>`; </div>`;
this.insertIntoDOM(modalHtml); this.insertIntoDOM(modalHtml);
} }
initializeTrigger() { initializeTrigger() {
this.getElement().addEventListener('click', () => { this.element.addEventListener('click', () => {
document.getElementById(this.getModalId()).classList.remove('hidden'); document.getElementById(this.id).classList.remove('hidden');
}); });
} }
} }
@ -979,7 +1044,7 @@
constructor(action) { constructor(action) {
this.#action = action; this.#action = action;
// Clear initial content // Clear initial content
this.getElement().innerHTML = ''; this.element.innerHTML = '';
} }
/** /**
@ -988,8 +1053,8 @@
* @param {string} content - The content to load into the trigger element. * @param {string} content - The content to load into the trigger element.
*/ */
load(content) { load(content) {
const existingContent = this.getElement().innerHTML; const existingContent = this.element.innerHTML;
this.getElement().innerHTML = existingContent ? `${existingContent}\n ${content}` : content; this.element.innerHTML = existingContent ? `${existingContent}\n ${content}` : content;
} }
/** /**
@ -997,8 +1062,8 @@
* *
* @returns {HTMLElement} - The DOM element being worked with. * @returns {HTMLElement} - The DOM element being worked with.
*/ */
getElement() { get element() {
return this.#action.getElement(); return this.#action.element;
} }
} }
@ -1012,7 +1077,7 @@
*/ */
constructor(action) { constructor(action) {
this.#action = action; this.#action = action;
this.getElement().style.cursor = 'help'; this.element.style.cursor = 'help';
} }
/** /**
@ -1023,9 +1088,9 @@
* @throws {Error} Throws an error if the trigger elements is not valid. * @throws {Error} Throws an error if the trigger elements is not valid.
*/ */
load(content) { load(content) {
const existingTitle = this.getElement().getAttribute('title'); const existingTitle = this.element.getAttribute('title');
const newTitle = existingTitle ? existingTitle + "\n" + content : content; const newTitle = existingTitle ? existingTitle + "\n" + content : content;
this.getElement().setAttribute('title', newTitle); this.element.setAttribute('title', newTitle);
} }
/** /**
@ -1033,8 +1098,8 @@
* *
* @returns {HTMLElement} - The DOM element being worked with. * @returns {HTMLElement} - The DOM element being worked with.
*/ */
getElement() { get element() {
return this.#action.getElement(); return this.#action.element;
} }
} }
@ -1057,14 +1122,14 @@
} }
class UikitTooltip extends BaseTooltip { class UikitTooltip extends BaseTooltip {
constructor(triggerElement) { constructor(action) {
super(triggerElement); super(action);
} }
load(content) { load(content) {
try { try {
super.load(content); super.load(content);
UIkit.tooltip(this.triggerElement); UIkit.tooltip(this.element);
} catch (error) { } catch (error) {
console.error('Error loading UikitTooltip:', error); console.error('Error loading UikitTooltip:', error);
} }
@ -1078,9 +1143,9 @@
load(content) { load(content) {
try { try {
this.getElement().setAttribute('data-tooltip', ''); this.element.setAttribute('data-tooltip', '');
super.load(content); super.load(content);
this.getElement().classList.add('has-tip'); this.element.classList.add('has-tip');
new Foundation.Tooltip(this.getElement(), { new Foundation.Tooltip(this.getElement(), {
// Default options // Default options
@ -1089,7 +1154,7 @@
fadeInDuration: 150, // Duration of fade in animation in milliseconds fadeInDuration: 150, // Duration of fade in animation in milliseconds
showOn: 'all', // Can be 'all', 'large', 'medium', 'small' showOn: 'all', // Can be 'all', 'large', 'medium', 'small'
templateClasses: '', // Custom class(es) to be added to the tooltip template templateClasses: '', // Custom class(es) to be added to the tooltip template
tipText: () => this.getElement().getAttribute('title'), // Function to define tooltip text tipText: () => this.element.getAttribute('title'), // Function to define tooltip text
triggerClass: 'has-tip', // Class to be added on the trigger elements triggerClass: 'has-tip', // Class to be added on the trigger elements
touchCloseText: 'tap to close', // Text for close button on touch devices touchCloseText: 'tap to close', // Text for close button on touch devices
positionClass: 'top', // Position of tooltip, can be 'top', 'bottom', 'left', 'right', etc. positionClass: 'top', // Position of tooltip, can be 'top', 'bottom', 'left', 'right', etc.
@ -1123,25 +1188,25 @@
this.tooltipElement.id = this.tooltipId; this.tooltipElement.id = this.tooltipId;
this.tooltipElement.className = 'absolute invisible bg-gray-800 text-white text-xs px-2 py-1 rounded-md'; this.tooltipElement.className = 'absolute invisible bg-gray-800 text-white text-xs px-2 py-1 rounded-md';
this.tooltipElement.style.transition = 'visibility 0.3s linear, opacity 0.3s linear'; this.tooltipElement.style.transition = 'visibility 0.3s linear, opacity 0.3s linear';
this.tooltipElement.textContent = this.getElement().getAttribute('title'); this.tooltipElement.textContent = this.element.getAttribute('title');
document.body.appendChild(this.tooltipElement); document.body.appendChild(this.tooltipElement);
} }
_initializeEvents() { _initializeEvents() {
this.getElement().addEventListener('mouseenter', () => { this.element.addEventListener('mouseenter', () => {
const rect = this.getElement().getBoundingClientRect(); const rect = this.element.getBoundingClientRect();
this._title = this.getElement().getAttribute('title'); this._title = this.element.getAttribute('title');
this.tooltipElement.style.left = `${rect.left + window.scrollX}px`; this.tooltipElement.style.left = `${rect.left + window.scrollX}px`;
this.tooltipElement.style.top = `${rect.bottom + 5 + window.scrollY}px`; this.tooltipElement.style.top = `${rect.bottom + 5 + window.scrollY}px`;
this.tooltipElement.classList.remove('invisible'); this.tooltipElement.classList.remove('invisible');
this.tooltipElement.classList.add('opacity-100'); this.tooltipElement.classList.add('opacity-100');
this.getElement().setAttribute('title', ''); this.element.setAttribute('title', '');
}); });
this.getElement().addEventListener('mouseleave', () => { this.element.addEventListener('mouseleave', () => {
this.tooltipElement.classList.add('invisible'); this.tooltipElement.classList.add('invisible');
this.tooltipElement.classList.remove('opacity-100'); this.tooltipElement.classList.remove('opacity-100');
this.getElement().setAttribute('title', this._title); this.element.setAttribute('title', this._title);
}); });
} }
} }
@ -1175,7 +1240,6 @@
* *
* @param {Action} action - The action element triggering the tooltip. * @param {Action} action - The action element triggering the tooltip.
* @returns {BaseTooltip|BootstrapTooltip|UikitTooltip|FoundationTooltip|TailwindTooltip} The tooltip instance. * @returns {BaseTooltip|BootstrapTooltip|UikitTooltip|FoundationTooltip|TailwindTooltip} The tooltip instance.
* @param debug
*/ */
static framework(action) { static framework(action) {
const frameworks = { const frameworks = {
@ -1218,7 +1282,7 @@
'tooltip': TooltipElement 'tooltip': TooltipElement
}; };
const format = action.getFormat(); const format = action.format;
const ElementType = elementTypes[format] || InlineElement; const ElementType = elementTypes[format] || InlineElement;
this.element = new ElementType(action); this.element = new ElementType(action);
@ -1252,7 +1316,7 @@
* Allows for dependency injection of the Api class for easier testing and flexibility. * Allows for dependency injection of the Api class for easier testing and flexibility.
* @param {Api} api - Instance of Api class for making API calls. * @param {Api} api - Instance of Api class for making API calls.
*/ */
constructor(api = new Api()) { constructor(api) {
this.#api = api; this.#api = api;
} }
@ -1307,7 +1371,7 @@
*/ */
async #processReferences(validReferences) { async #processReferences(validReferences) {
for (const reference of validReferences) { for (const reference of validReferences) {
for (const translation of this.#action.getTranslations()) { for (const translation of this.#action.translations) {
try { try {
const scripture = await this.#api.get(reference, translation); const scripture = await this.#api.get(reference, translation);
if (scripture) { if (scripture) {

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
"name": "getbible.loader", "name": "getbible.loader",
"title": "getBible", "title": "getBible",
"description": "GetBible is an intuitive and lightweight JavaScript solution for embedding Bible scripture into your website.", "description": "GetBible is an intuitive and lightweight JavaScript solution for embedding Bible scripture into your website.",
"version": "3.0.2", "version": "3.0.3",
"main": "dist/js/getBible.min.js", "main": "dist/js/getBible.min.js",
"scripts": { "scripts": {
"build": "rollup -c" "build": "rollup -c"

View File

@ -7,9 +7,11 @@ export class Action {
#translations; #translations;
#showBookName; #showBookName;
#showReference; #showReference;
#showLocalReference;
#showTranslation; #showTranslation;
#showAbbreviation; #showAbbreviation;
#showLanguage; #showLanguage;
#showLanguageCode;
/** /**
* Initializes the Actions object with a DOM element and its data attributes. * Initializes the Actions object with a DOM element and its data attributes.
@ -27,9 +29,15 @@ export class Action {
this.#translations = (element.dataset.translation || 'kjv').toLowerCase().split(';').map(translation => translation.trim()); this.#translations = (element.dataset.translation || 'kjv').toLowerCase().split(';').map(translation => translation.trim());
this.#showBookName = element.dataset.showBookName ? parseInt(element.dataset.showBookName, 10) : 0; this.#showBookName = element.dataset.showBookName ? parseInt(element.dataset.showBookName, 10) : 0;
this.#showReference = element.dataset.showReference ? parseInt(element.dataset.showReference, 10) : 1; this.#showReference = element.dataset.showReference ? parseInt(element.dataset.showReference, 10) : 1;
this.#showLocalReference = element.dataset.showLocalReference ? parseInt(element.dataset.showLocalReference, 10) : 0;
this.#showTranslation = element.dataset.showTranslation ? parseInt(element.dataset.showTranslation, 10) : 0; this.#showTranslation = element.dataset.showTranslation ? parseInt(element.dataset.showTranslation, 10) : 0;
this.#showAbbreviation = element.dataset.showAbbreviation ? parseInt(element.dataset.showAbbreviation, 10) : 0; this.#showAbbreviation = element.dataset.showAbbreviation ? parseInt(element.dataset.showAbbreviation, 10) : 0;
this.#showLanguage = element.dataset.showLanguage ? parseInt(element.dataset.showLanguage, 10) : 0; this.#showLanguage = element.dataset.showLanguage ? parseInt(element.dataset.showLanguage, 10) : 0;
this.#showLanguageCode = element.dataset.showLanguageCode ? parseInt(element.dataset.showLanguageCode, 10) : 0;
if (this.#showLocalReference){
this.#showReference = 0;
}
} }
/** /**
@ -37,7 +45,7 @@ export class Action {
* *
* @returns {Array<string>} An array of translation strings. * @returns {Array<string>} An array of translation strings.
*/ */
getTranslations() { get translations() {
return this.#translations; return this.#translations;
} }
@ -46,7 +54,7 @@ export class Action {
* *
* @returns {number} The show book name flag (0 or 1). * @returns {number} The show book name flag (0 or 1).
*/ */
showBookName() { get bookName() {
return this.#showBookName; return this.#showBookName;
} }
@ -55,16 +63,25 @@ export class Action {
* *
* @returns {number} The show reference flag (0 or 1). * @returns {number} The show reference flag (0 or 1).
*/ */
showReference() { get reference() {
return this.#showReference; return this.#showReference;
} }
/**
* Retrieves the show local reference flag.
*
* @returns {number} The show reference flag (0 or 1).
*/
get localReference() {
return this.#showLocalReference;
}
/** /**
* Retrieves the show translation flag. * Retrieves the show translation flag.
* *
* @returns {number} The show translation flag (0 or 1). * @returns {number} The show translation flag (0 or 1).
*/ */
showTranslation() { get translation() {
return this.#showTranslation; return this.#showTranslation;
} }
@ -73,7 +90,7 @@ export class Action {
* *
* @returns {number} The show abbreviation flag (0 or 1). * @returns {number} The show abbreviation flag (0 or 1).
*/ */
showAbbreviation() { get abbreviation() {
return this.#showAbbreviation; return this.#showAbbreviation;
} }
@ -82,16 +99,25 @@ export class Action {
* *
* @returns {number} The show language flag (0 or 1). * @returns {number} The show language flag (0 or 1).
*/ */
showLanguage() { get language() {
return this.#showLanguage; return this.#showLanguage;
} }
/**
* Retrieves the show language code flog.
*
* @returns {number} The show language flag (0 or 1).
*/
get languageCode() {
return this.#showLanguageCode;
}
/** /**
* Retrieves the element format. * Retrieves the element format.
* *
* @returns {string} The element format. * @returns {string} The element format.
*/ */
getFormat() { get format() {
return this.#format; return this.#format;
} }
@ -100,7 +126,7 @@ export class Action {
* *
* @returns {HTMLElement} The DOM element associated with this object. * @returns {HTMLElement} The DOM element associated with this object.
*/ */
getElement() { get element() {
return this.#element; return this.#element;
} }
} }

View File

@ -19,7 +19,7 @@ export class Loader {
* Allows for dependency injection of the Api class for easier testing and flexibility. * Allows for dependency injection of the Api class for easier testing and flexibility.
* @param {Api} api - Instance of Api class for making API calls. * @param {Api} api - Instance of Api class for making API calls.
*/ */
constructor(api = new Api()) { constructor(api) {
this.#api = api; this.#api = api;
} }
@ -74,7 +74,7 @@ export class Loader {
*/ */
async #processReferences(validReferences) { async #processReferences(validReferences) {
for (const reference of validReferences) { for (const reference of validReferences) {
for (const translation of this.#action.getTranslations()) { for (const translation of this.#action.translations) {
try { try {
const scripture = await this.#api.get(reference, translation); const scripture = await this.#api.get(reference, translation);
if (scripture) { if (scripture) {

View File

@ -8,8 +8,38 @@ export class Reference {
* Initializes the BibleVerse object with verse data. * Initializes the BibleVerse object with verse data.
* *
* @param {Object} data - The JSON data containing verse information. * @param {Object} data - The JSON data containing verse information.
* @param {string} data.translation - The name of the translation.
* @param {string} data.abbreviation - The abbreviation of the translation.
* @param {string} data.language - The full language name.
* @param {string} data.lang - The language code.
* @param {string} data.direction - The text direction (LTR or RTL).
* @param {string} data.encoding - The encoding format (e.g., UTF-8).
* @param {number} data.book_nr - The book number.
* @param {string} data.book_name - The name of the book.
* @param {number} data.chapter - The chapter number.
* @param {string} data.name - The name of the chapter.
* @param {Array<Object>} data.verses - An array of objects representing each verse.
* @param {string|Array<string>} data.ref - The local reference string or array of strings.
*/ */
constructor(data) { constructor(data) {
// Simple validation to check if essential properties are present
const requiredProperties = [
'translation', 'abbreviation', 'language', 'lang',
'direction', 'encoding', 'book_nr', 'book_name',
'chapter', 'name', 'verses', 'ref'
];
if (!data || typeof data !== 'object') {
throw new Error('Data must be a valid object.');
}
requiredProperties.forEach(prop => {
if (data[prop] === undefined || data[prop] === null) {
throw new Error(`Missing required property: '${prop}'.`);
}
});
// Assign the data after validation
this.#data = data; this.#data = data;
} }
@ -18,7 +48,7 @@ export class Reference {
* *
* @returns {string} The name of the translation. * @returns {string} The name of the translation.
*/ */
getTranslation() { get translation() {
return this.#data.translation; return this.#data.translation;
} }
@ -27,26 +57,26 @@ export class Reference {
* *
* @returns {string} The abbreviation of the translation. * @returns {string} The abbreviation of the translation.
*/ */
getAbbreviation() { get abbreviation() {
return this.#data.abbreviation; return this.#data.abbreviation;
} }
/**
* Retrieves the language code.
*
* @returns {string} The language code.
*/
getLanguage() {
return this.#data.lang;
}
/** /**
* Retrieves the full language name. * Retrieves the full language name.
* *
* @returns {string} The language code.
*/
get language() {
return this.#data.language;
}
/**
* Retrieves the language code.
*
* @returns {string} The full name of the language. * @returns {string} The full name of the language.
*/ */
getLanguageName() { get languageCode() {
return this.#data.language; return this.#data.lang;
} }
/** /**
@ -54,7 +84,7 @@ export class Reference {
* *
* @returns {string} The direction of the text (LTR or RTL). * @returns {string} The direction of the text (LTR or RTL).
*/ */
getTextDirection() { get textDirection() {
return this.#data.direction; return this.#data.direction;
} }
@ -63,7 +93,7 @@ export class Reference {
* *
* @returns {string} The encoding format (e.g., UTF-8). * @returns {string} The encoding format (e.g., UTF-8).
*/ */
getEncoding() { get encoding() {
return this.#data.encoding; return this.#data.encoding;
} }
@ -72,7 +102,7 @@ export class Reference {
* *
* @returns {number} The book number. * @returns {number} The book number.
*/ */
getBookNumber() { get bookNumber() {
return this.#data.book_nr; return this.#data.book_nr;
} }
@ -81,7 +111,7 @@ export class Reference {
* *
* @returns {string} The name of the book. * @returns {string} The name of the book.
*/ */
getBookName() { get bookName() {
return this.#data.book_name; return this.#data.book_name;
} }
@ -90,7 +120,7 @@ export class Reference {
* *
* @returns {number} The chapter number. * @returns {number} The chapter number.
*/ */
getChapter() { get chapter() {
return this.#data.chapter; return this.#data.chapter;
} }
@ -99,16 +129,17 @@ export class Reference {
* *
* @returns {string} The name of the chapter. * @returns {string} The name of the chapter.
*/ */
getChapterName() { get chapterName() {
return this.#data.name; return this.#data.name;
} }
/** /**
* Retrieves all verses of the chapter. * Retrieves all verses of the chapter.
* *
* @returns {Array<Object>} An array of objects representing each verse. * @returns {Array<{chapter: number, verse: number, name: string, text: string}>}
* An array of objects representing each verse.
*/ */
getVerses() { get verses() {
return this.#data.verses; return this.#data.verses;
} }
@ -133,12 +164,22 @@ export class Reference {
return this.#data.verses.filter(verse => verse.verse >= startVerse && verse.verse <= endVerse); return this.#data.verses.filter(verse => verse.verse >= startVerse && verse.verse <= endVerse);
} }
/**
* Get the local reference string set in the website.
*
* @returns {string} The reference string.
*/
get localReference() {
// Ensure that this.#data.ref is treated as an array.
return Array.isArray(this.#data.ref) ? this.#data.ref.join('; ') : this.#data.ref;
}
/** /**
* Generates a reference string for the verses. * Generates a reference string for the verses.
* *
* @returns {string} The reference string. * @returns {string} The reference string.
*/ */
getReference() { get reference() {
const verseNumbers = this.#data.verses.map(verse => verse.verse).sort((a, b) => a - b); const verseNumbers = this.#data.verses.map(verse => verse.verse).sort((a, b) => a - b);
let refString = `${this.#data.name}:`; let refString = `${this.#data.name}:`;
let ranges = {}; let ranges = {};

View File

@ -15,26 +15,6 @@ export class Scripture {
this.#references = Object.values(data).map(reference => new Reference(reference)); this.#references = Object.values(data).map(reference => new Reference(reference));
} }
/**
* Gets a reference by its numerical index.
*
* @param {number} index - The index of the reference.
* @returns {Reference|null} The Reference instance or null if out of bounds.
*/
getReference(index) {
return (index >= 0 && index < this.#references.length) ? this.#references[index] : null;
}
/**
* Gets the translation.
*
* @param {number} index - The index of the reference.
* @returns {Reference|null} The Reference instance or null if out of bounds.
*/
getReference(index) {
return (index >= 0 && index < this.#references.length) ? this.#references[index] : null;
}
/** /**
* Iterates over all references and performs a callback function. * Iterates over all references and performs a callback function.
* *

View File

@ -20,7 +20,7 @@ export class Element {
'tooltip': TooltipElement 'tooltip': TooltipElement
}; };
const format = action.getFormat(); const format = action.format;
const ElementType = elementTypes[format] || InlineElement; const ElementType = elementTypes[format] || InlineElement;
this.element = new ElementType(action); this.element = new ElementType(action);

View File

@ -14,7 +14,7 @@ export class InlineElement {
constructor(action) { constructor(action) {
this.#action = action; this.#action = action;
// Clear initial content // Clear initial content
this.getElement().innerHTML = ''; this.element.innerHTML = '';
} }
/** /**
@ -23,8 +23,8 @@ export class InlineElement {
* @param {string} content - The content to load into the trigger element. * @param {string} content - The content to load into the trigger element.
*/ */
load(content) { load(content) {
const existingContent = this.getElement().innerHTML; const existingContent = this.element.innerHTML;
this.getElement().innerHTML = existingContent ? `${existingContent}\n ${content}` : content; this.element.innerHTML = existingContent ? `${existingContent}\n ${content}` : content;
} }
/** /**
@ -32,7 +32,7 @@ export class InlineElement {
* *
* @returns {HTMLElement} - The DOM element being worked with. * @returns {HTMLElement} - The DOM element being worked with.
*/ */
getElement() { get element() {
return this.#action.getElement(); return this.#action.element;
} }
} }

View File

@ -34,7 +34,6 @@ export class TooltipElement {
* *
* @param {Action} action - The action element triggering the tooltip. * @param {Action} action - The action element triggering the tooltip.
* @returns {BaseTooltip|BootstrapTooltip|UikitTooltip|FoundationTooltip|TailwindTooltip} The tooltip instance. * @returns {BaseTooltip|BootstrapTooltip|UikitTooltip|FoundationTooltip|TailwindTooltip} The tooltip instance.
* @param debug
*/ */
static framework(action) { static framework(action) {
const frameworks = { const frameworks = {

View File

@ -12,7 +12,7 @@ export class BaseModal {
constructor(action) { constructor(action) {
this.#modalId = `modal-${Math.random().toString(36).slice(2, 11)}`; this.#modalId = `modal-${Math.random().toString(36).slice(2, 11)}`;
this.#action = action; this.#action = action;
this.getElement().style.cursor = 'pointer'; this.element.style.cursor = 'pointer';
this.initializeTrigger(); this.initializeTrigger();
} }
@ -22,11 +22,11 @@ export class BaseModal {
* @param {string} content - The content to load into the modal. * @param {string} content - The content to load into the modal.
*/ */
load(content) { load(content) {
const existingModal = document.getElementById(this.getModalId()); const existingModal = document.getElementById(this.id);
// Check if modal already exists // Check if modal already exists
if (existingModal) { if (existingModal) {
// Update the content of the existing modal // Update the content of the existing modal
const contentDiv = document.getElementById(`${this.getModalId()}-content`); const contentDiv = document.getElementById(`${this.id}-content`);
if (contentDiv) { if (contentDiv) {
contentDiv.innerHTML += content; contentDiv.innerHTML += content;
} }
@ -52,17 +52,17 @@ export class BaseModal {
*/ */
create(content) { create(content) {
const modalHtml = ` const modalHtml = `
<div id="${this.getModalId()}" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background-color:rgba(0, 0, 0, 0.5); justify-content:center; align-items:center;"> <div id="${this.id}" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background-color:rgba(0, 0, 0, 0.5); justify-content:center; align-items:center;">
<div style="position:relative; background-color:white; padding:20px; border-radius:5px; max-width:300px;"> <div style="position:relative; background-color:white; padding:20px; border-radius:5px; max-width:300px;">
<button class="getbible-modal-close" type="button" onclick="document.getElementById('${this.getModalId()}').style.display='none'" style="position:absolute; top:7px; right:7px; border:none; background:transparent; font-size:20px; cursor:pointer;"></button> <button class="getbible-modal-close" type="button" onclick="document.getElementById('${this.id}').style.display='none'" style="position:absolute; top:7px; right:7px; border:none; background:transparent; font-size:20px; cursor:pointer;"></button>
<div id="${this.getModalId()}-content"> <div id="${this.id}-content">
${content} ${content}
</div> </div>
</div> </div>
</div>`; </div>`;
this.insertIntoDOM(modalHtml); this.insertIntoDOM(modalHtml);
const modalElement = document.getElementById(this.getModalId()); const modalElement = document.getElementById(this.id);
modalElement.addEventListener('click', (event) => { modalElement.addEventListener('click', (event) => {
if (event.target === modalElement) { if (event.target === modalElement) {
modalElement.style.display = 'none'; modalElement.style.display = 'none';
@ -75,8 +75,8 @@ export class BaseModal {
* *
*/ */
initializeTrigger() { initializeTrigger() {
this.getElement().addEventListener('click', () => { this.element.addEventListener('click', () => {
document.getElementById(this.getModalId()).style.display = 'flex'; document.getElementById(this.id).style.display = 'flex';
}); });
} }
@ -85,7 +85,7 @@ export class BaseModal {
* *
* @returns {string} - The modal ID * @returns {string} - The modal ID
*/ */
getModalId() { get id() {
return this.#modalId; return this.#modalId;
} }
@ -94,7 +94,7 @@ export class BaseModal {
* *
* @returns {HTMLElement} - The DOM element being worked with. * @returns {HTMLElement} - The DOM element being worked with.
*/ */
getElement() { get element() {
return this.#action.getElement(); return this.#action.element;
} }
} }

View File

@ -6,12 +6,12 @@ export class BootstrapModal extends BaseModal {
} }
show() { show() {
const modal = new bootstrap.Modal(document.getElementById(this.getModalId())); const modal = new bootstrap.Modal(document.getElementById(this.id));
modal.show(); modal.show();
} }
hide() { hide() {
const modal = bootstrap.Modal.getInstance(document.getElementById(this.getModalId())); const modal = bootstrap.Modal.getInstance(document.getElementById(this.id));
if (modal) { if (modal) {
modal.hide(); modal.hide();
} }
@ -19,13 +19,13 @@ export class BootstrapModal extends BaseModal {
create(content) { create(content) {
const modalHtml = ` const modalHtml = `
<div class="modal fade" id="${this.getModalId()}" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal fade" id="${this.id}" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content p-3"> <div class="modal-content p-3">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div id="${this.getModalId()}-content" class="modal-body"> <div id="${this.id}-content" class="modal-body">
${content} ${content}
</div> </div>
</div> </div>
@ -35,7 +35,7 @@ export class BootstrapModal extends BaseModal {
} }
initializeTrigger() { initializeTrigger() {
this.getElement().setAttribute('data-bs-toggle', 'modal'); this.element.setAttribute('data-bs-toggle', 'modal');
this.getElement().setAttribute('data-bs-target', `#${this.getModalId()}`); this.element.setAttribute('data-bs-target', `#${this.id}`);
} }
} }

View File

@ -20,8 +20,8 @@ export class FoundationModal extends BaseModal {
create(content) { create(content) {
const modalHtml = ` const modalHtml = `
<div class="reveal" id="${this.getModalId()}" data-reveal> <div class="reveal" id="${this.id}" data-reveal>
<div id="${this.getModalId()}-content"> <div id="${this.id}-content">
${content} ${content}
</div> </div>
<button class="close-button" data-close aria-label="Close modal" type="button"> <button class="close-button" data-close aria-label="Close modal" type="button">
@ -29,10 +29,10 @@ export class FoundationModal extends BaseModal {
</button> </button>
</div>`; </div>`;
this.insertIntoDOM(modalHtml); this.insertIntoDOM(modalHtml);
this.modalElement = new Foundation.Reveal(document.getElementById(this.getModalId())); this.modalElement = new Foundation.Reveal(document.getElementById(this.id));
} }
initializeTrigger() { initializeTrigger() {
this.getElement().setAttribute('data-open', this.getModalId()); this.element.setAttribute('data-open', this.id);
} }
} }

View File

@ -6,29 +6,29 @@ export class TailwindModal extends BaseModal {
} }
show() { show() {
document.getElementById(this.getModalId()).classList.remove('hidden'); document.getElementById(this.id).classList.remove('hidden');
} }
hide() { hide() {
document.getElementById(this.getModalId()).classList.add('hidden'); document.getElementById(this.id).classList.add('hidden');
} }
create(content) { create(content) {
const modalHtml = ` const modalHtml = `
<div class="modal hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full" id="${this.getModalId()}"> <div class="modal hidden fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full" id="${this.id}">
<div class="modal-content container mx-auto p-5 bg-white"> <div class="modal-content container mx-auto p-5 bg-white">
<div id="${this.getModalId()}-content"> <div id="${this.id}-content">
${content} ${content}
</div> </div>
<button class="close-button" onclick="document.getElementById('${this.getModalId()}').classList.add('hidden')">Close</button> <button class="close-button" onclick="document.getElementById('${this.id}').classList.add('hidden')">Close</button>
</div> </div>
</div>`; </div>`;
this.insertIntoDOM(modalHtml); this.insertIntoDOM(modalHtml);
} }
initializeTrigger() { initializeTrigger() {
this.getElement().addEventListener('click', () => { this.element.addEventListener('click', () => {
document.getElementById(this.getModalId()).classList.remove('hidden'); document.getElementById(this.id).classList.remove('hidden');
}); });
} }
} }

View File

@ -6,19 +6,19 @@ export class UikitModal extends BaseModal {
} }
show() { show() {
UIkit.modal(`#${this.getModalId()}`).show(); UIkit.modal(`#${this.id}`).show();
} }
hide() { hide() {
UIkit.modal(`#${this.getModalId()}`).hide(); UIkit.modal(`#${this.id}`).hide();
} }
create(content) { create(content) {
const modalHtml = ` const modalHtml = `
<div id="${this.getModalId()}" uk-modal> <div id="${this.id}" uk-modal>
<div class="uk-modal-dialog uk-modal-body"> <div class="uk-modal-dialog uk-modal-body">
<button class="uk-modal-close-default" type="button" uk-close></button> <button class="uk-modal-close-default" type="button" uk-close></button>
<div id="${this.getModalId()}-content"> <div id="${this.id}-content">
${content} ${content}
</div> </div>
</div> </div>
@ -27,7 +27,7 @@ export class UikitModal extends BaseModal {
} }
initializeTrigger() { initializeTrigger() {
this.getElement().setAttribute('uk-toggle', `target: #${this.getModalId()}`); this.element.setAttribute('uk-toggle', `target: #${this.id}`);
} }
} }

View File

@ -10,7 +10,7 @@ export class BaseTooltip {
*/ */
constructor(action) { constructor(action) {
this.#action = action; this.#action = action;
this.getElement().style.cursor = 'help'; this.element.style.cursor = 'help';
} }
/** /**
@ -21,9 +21,9 @@ export class BaseTooltip {
* @throws {Error} Throws an error if the trigger elements is not valid. * @throws {Error} Throws an error if the trigger elements is not valid.
*/ */
load(content) { load(content) {
const existingTitle = this.getElement().getAttribute('title'); const existingTitle = this.element.getAttribute('title');
const newTitle = existingTitle ? existingTitle + "\n" + content : content; const newTitle = existingTitle ? existingTitle + "\n" + content : content;
this.getElement().setAttribute('title', newTitle); this.element.setAttribute('title', newTitle);
} }
/** /**
@ -31,7 +31,7 @@ export class BaseTooltip {
* *
* @returns {HTMLElement} - The DOM element being worked with. * @returns {HTMLElement} - The DOM element being worked with.
*/ */
getElement() { get element() {
return this.#action.getElement(); return this.#action.element;
} }
} }

View File

@ -7,9 +7,9 @@ export class FoundationTooltip extends BaseTooltip {
load(content) { load(content) {
try { try {
this.getElement().setAttribute('data-tooltip', ''); this.element.setAttribute('data-tooltip', '');
super.load(content); super.load(content);
this.getElement().classList.add('has-tip'); this.element.classList.add('has-tip');
new Foundation.Tooltip(this.getElement(), { new Foundation.Tooltip(this.getElement(), {
// Default options // Default options
@ -18,7 +18,7 @@ export class FoundationTooltip extends BaseTooltip {
fadeInDuration: 150, // Duration of fade in animation in milliseconds fadeInDuration: 150, // Duration of fade in animation in milliseconds
showOn: 'all', // Can be 'all', 'large', 'medium', 'small' showOn: 'all', // Can be 'all', 'large', 'medium', 'small'
templateClasses: '', // Custom class(es) to be added to the tooltip template templateClasses: '', // Custom class(es) to be added to the tooltip template
tipText: () => this.getElement().getAttribute('title'), // Function to define tooltip text tipText: () => this.element.getAttribute('title'), // Function to define tooltip text
triggerClass: 'has-tip', // Class to be added on the trigger elements triggerClass: 'has-tip', // Class to be added on the trigger elements
touchCloseText: 'tap to close', // Text for close button on touch devices touchCloseText: 'tap to close', // Text for close button on touch devices
positionClass: 'top', // Position of tooltip, can be 'top', 'bottom', 'left', 'right', etc. positionClass: 'top', // Position of tooltip, can be 'top', 'bottom', 'left', 'right', etc.

View File

@ -20,25 +20,25 @@ export class TailwindTooltip extends BaseTooltip {
this.tooltipElement.id = this.tooltipId; this.tooltipElement.id = this.tooltipId;
this.tooltipElement.className = 'absolute invisible bg-gray-800 text-white text-xs px-2 py-1 rounded-md'; this.tooltipElement.className = 'absolute invisible bg-gray-800 text-white text-xs px-2 py-1 rounded-md';
this.tooltipElement.style.transition = 'visibility 0.3s linear, opacity 0.3s linear'; this.tooltipElement.style.transition = 'visibility 0.3s linear, opacity 0.3s linear';
this.tooltipElement.textContent = this.getElement().getAttribute('title'); this.tooltipElement.textContent = this.element.getAttribute('title');
document.body.appendChild(this.tooltipElement); document.body.appendChild(this.tooltipElement);
} }
_initializeEvents() { _initializeEvents() {
this.getElement().addEventListener('mouseenter', () => { this.element.addEventListener('mouseenter', () => {
const rect = this.getElement().getBoundingClientRect(); const rect = this.element.getBoundingClientRect();
this._title = this.getElement().getAttribute('title'); this._title = this.element.getAttribute('title');
this.tooltipElement.style.left = `${rect.left + window.scrollX}px`; this.tooltipElement.style.left = `${rect.left + window.scrollX}px`;
this.tooltipElement.style.top = `${rect.bottom + 5 + window.scrollY}px`; this.tooltipElement.style.top = `${rect.bottom + 5 + window.scrollY}px`;
this.tooltipElement.classList.remove('invisible'); this.tooltipElement.classList.remove('invisible');
this.tooltipElement.classList.add('opacity-100'); this.tooltipElement.classList.add('opacity-100');
this.getElement().setAttribute('title', ''); this.element.setAttribute('title', '');
}); });
this.getElement().addEventListener('mouseleave', () => { this.element.addEventListener('mouseleave', () => {
this.tooltipElement.classList.add('invisible'); this.tooltipElement.classList.add('invisible');
this.tooltipElement.classList.remove('opacity-100'); this.tooltipElement.classList.remove('opacity-100');
this.getElement().setAttribute('title', this._title); this.element.setAttribute('title', this._title);
}); });
} }
} }

View File

@ -1,14 +1,14 @@
import {BaseTooltip} from './BaseTooltip.js'; import {BaseTooltip} from './BaseTooltip.js';
export class UikitTooltip extends BaseTooltip { export class UikitTooltip extends BaseTooltip {
constructor(triggerElement) { constructor(action) {
super(triggerElement); super(action);
} }
load(content) { load(content) {
try { try {
super.load(content); super.load(content);
UIkit.tooltip(this.triggerElement); UIkit.tooltip(this.element);
} catch (error) { } catch (error) {
console.error('Error loading UikitTooltip:', error); console.error('Error loading UikitTooltip:', error);
} }

View File

@ -18,7 +18,7 @@ export class BaseFormat {
* *
* @returns {Action} The current actions. * @returns {Action} The current actions.
*/ */
action() { get action() {
return this.#action; return this.#action;
} }

View File

@ -16,27 +16,33 @@ export class BlockFormat extends BaseFormat {
let display = []; let display = [];
scripture.forEachReference((reference) => { scripture.forEachReference((reference) => {
let header = []; let header = [];
display.push(`<div dir="${reference.getTextDirection().toUpperCase()}" class="getbible-reference-block">`); display.push(`<div dir="${reference.textDirection.toUpperCase()}" class="getbible-reference-block">`);
if (this.action().showBookName()) { if (this.action.bookName) {
header.push(`<span class="getbible-book-name">${reference.getBookName()}</span>`); header.push(`<span class="getbible-book-name">${reference.bookName}</span>`);
} }
if (this.action().showReference()) { if (this.action.reference) {
header.push(`<span class="getbible-reference">${reference.getReference()}</span>`); header.push(`<span class="getbible-reference">${reference.reference}</span>`);
} }
if (this.action().showTranslation()) { if (this.action.localReference) {
header.push(`<span class="getbible-translation">${reference.getTranslation()}</span>`); header.push(`<span class="getbible-reference">${reference.localReference}</span>`);
} }
if (this.action().showAbbreviation()) { if (this.action.translation) {
header.push(`<span class="getbible-abbreviation">${reference.getAbbreviation()}</span>`); header.push(`<span class="getbible-translation">${reference.translation}</span>`);
} }
if (this.action().showLanguage()) { if (this.action.abbreviation) {
header.push(`<span class="getbible-language">${reference.getLanguage()}</span>`); header.push(`<span class="getbible-abbreviation">${reference.abbreviation}</span>`);
}
if (this.action.language) {
header.push(`<span class="getbible-language">${reference.language}</span>`);
}
if (this.action.languageCode) {
header.push(`<span class="getbible-language-code">${reference.languageCode}</span>`);
} }
// Construct the header // Construct the header
if (header.length > 0) { if (header.length > 0) {
display.push(`<b class="getbible-header">${header.join(' - ')}</b>`); display.push(`<b class="getbible-header">${header.join(' - ')}</b>`);
} }
const verses = reference.getVerses() const verses = reference.verses
.map(verse => `<div class="getbible-verse">${verse.verse}. ${verse.text}</div>`) .map(verse => `<div class="getbible-verse">${verse.verse}. ${verse.text}</div>`)
.join("\n"); .join("\n");
display.push(`<div class="getbible-verses">${verses}</div>`); display.push(`<div class="getbible-verses">${verses}</div>`);

View File

@ -21,7 +21,7 @@ export class Format {
'tooltip': PlainFormat 'tooltip': PlainFormat
}; };
const format = action.getFormat(); const format = action.format;
const FormatType = formatTypes[format] || InlineFormat; const FormatType = formatTypes[format] || InlineFormat;
this.format = new FormatType(action); this.format = new FormatType(action);
} }

View File

@ -16,23 +16,29 @@ export class InlineFormat extends BaseFormat {
let display = []; let display = [];
scripture.forEachReference((reference) => { scripture.forEachReference((reference) => {
let footer = []; let footer = [];
display.push(`<div dir="${reference.getTextDirection().toUpperCase()}" class="getbible-reference-inline">`); display.push(`<div dir="${reference.textDirection.toUpperCase()}" class="getbible-reference-inline">`);
if (this.action().showBookName()) { if (this.action.bookName) {
footer.push(`<span class="getbible-book-name">${reference.getBookName()}</span>`); footer.push(`<span class="getbible-book-name">${reference.bookName}</span>`);
} }
if (this.action().showReference()) { if (this.action.reference) {
footer.push(`<span class="getbible-reference">${reference.getReference()}</span>`); footer.push(`<span class="getbible-reference">${reference.reference}</span>`);
} }
if (this.action().showTranslation()) { if (this.action.localReference) {
footer.push(`<span class="getbible-translation">${reference.getTranslation()}</span>`); footer.push(`<span class="getbible-reference">${reference.localReference}</span>`);
} }
if (this.action().showAbbreviation()) { if (this.action.translation) {
footer.push(`<span class="getbible-abbreviation">${reference.getAbbreviation()}</span>`); footer.push(`<span class="getbible-translation">${reference.translation}</span>`);
} }
if (this.action().showLanguage()) { if (this.action.abbreviation) {
footer.push(`<span class="getbible-language">${reference.getLanguage()}</span>`); footer.push(`<span class="getbible-abbreviation">${reference.abbreviation}</span>`);
} }
const verses = reference.getVerses() if (this.action.language) {
footer.push(`<span class="getbible-language">${reference.language}</span>`);
}
if (this.action.languageCode) {
footer.push(`<span class="getbible-language-code">${reference.languageCode}</span>`);
}
const verses = reference.verses
.map(verse => `<span class="getbible-verse">${verse.verse}. ${verse.text}</span>`) .map(verse => `<span class="getbible-verse">${verse.verse}. ${verse.text}</span>`)
.join("\n"); .join("\n");
display.push(`<span class="getbible-verses">${verses}</span>`); display.push(`<span class="getbible-verses">${verses}</span>`);

View File

@ -16,27 +16,33 @@ export class PlainFormat extends BaseFormat {
let display = []; let display = [];
scripture.forEachReference((reference) => { scripture.forEachReference((reference) => {
let header = []; let header = [];
if (this.action().showBookName()) { if (this.action.bookName) {
header.push(`${reference.getBookName()}`); header.push(`${reference.bookName}`);
} }
if (this.action().showReference()) { if (this.action.reference) {
header.push(`${reference.getReference()}`); header.push(`${reference.reference}`);
} }
if (this.action().showTranslation()) { if (this.action.localReference) {
header.push(`${reference.getTranslation()}`); header.push(`${reference.localReference}`);
} }
if (this.action().showAbbreviation()) { if (this.action.translation) {
header.push(`${reference.getAbbreviation()}`); header.push(`${reference.translation}`);
} }
if (this.action().showLanguage()) { if (this.action.abbreviation) {
header.push(`${reference.getLanguage()}`); header.push(`${reference.abbreviation}`);
}
if (this.action.language) {
header.push(`${reference.language}`);
}
if (this.action.languageCode) {
header.push(`${reference.languageCode}`);
} }
// Construct the header // Construct the header
if (header.length > 0) { if (header.length > 0) {
display.push(`[${header.join(' - ')}]`); display.push(`[${header.join(' - ')}]`);
} }
display.push( display.push(
reference.getVerses() reference.verses
.map(verse => `${verse.verse}. ${verse.text}`) .map(verse => `${verse.verse}. ${verse.text}`)
.join("\n") .join("\n")
); );

View File

@ -26,10 +26,10 @@
<li class="getBible" data-translation="kjv;aov" data-show-translation="1" data-show-language="1" <li class="getBible" data-translation="kjv;aov" data-show-translation="1" data-show-language="1"
data-format="tooltip">John 3:16,19 data-format="tooltip">John 3:16,19
</li> </li>
<li class="getBible" data-translation="kjv;aov" data-show-abbreviation="1" data-format="modal">John 3:16-17; 1 John 3:16-19,22</li> <li class="getBible" data-translation="kjv;aov" data-show-abbreviation="1" data-show-language-code="1" data-format="modal">John 3:16-17; 1 John 3:16-19,22</li>
<li class="getBible" data-translation="kjv;codex" data-show-language="1" data-format="modal">Genesis 1:1</li> <li class="getBible" data-translation="kjv;codex" data-show-language="1" data-format="modal">Genesis 1:1</li>
<li class="getBible" data-translation="kjv;codex" data-show-language="1" data-format="tooltip">Psalms 23:1-4</li> <li class="getBible" data-translation="kjv;codex" data-show-language="1" data-format="tooltip">Psalms 23:1-4</li>
<li class="getBible">Romans 8:28,31-39</li> <li class="getBible">Rom 8:28,31-39</li>
</ul> </ul>
</body> </body>