Skip to content

Feature/Search/683 #805

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 86 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
4dd4980
Create route for lexicon page
aidanpscott Nov 11, 2024
0bb0066
Removed page.ts
EthanFennell Feb 15, 2025
72193cf
Changed use of "slot" to "render" for navbar
EthanFennell Feb 15, 2025
571a598
List of words
EthanFennell Feb 16, 2025
00dd928
Fix mobile layout
aidanpscott Feb 20, 2025
a84899f
Fix lexicon auto load
aidanpscott Feb 21, 2025
c715b7e
Fix word id mismatch
MrCars0n Feb 21, 2025
4179fd2
Add margins to alphabet strip
aidanpscott Feb 21, 2025
8eca3d2
Add first draft of vernacular letter id handling
MrCars0n Feb 21, 2025
a58354e
Restore dictionary functionality while preserving styling
aidanpscott Feb 21, 2025
5058ec6
Fixed vernacular letter id handling
MrCars0n Feb 21, 2025
f505b2e
Create XML element and reorganize
MrCars0n Feb 24, 2025
58efc39
Fix loading of second letter on tab change
MrCars0n Feb 24, 2025
c267da7
Fix alphabet bar navigation bug
MrCars0n Feb 24, 2025
f55f09d
Store selectedLanguage after XMLView
MrCars0n Mar 1, 2025
59abc83
Add word subtexts, indexes, and alphabet strip size change
MrCars0n Mar 2, 2025
eb3439d
add single entry style type
AslanRules Mar 24, 2025
bb25aaf
Add word navigation component
aidanpscott Mar 3, 2025
5db8f03
Add XML new lines
MrCars0n Mar 3, 2025
8ab79df
Add multi-index XML call and new line formatting
MrCars0n Mar 5, 2025
8593163
Bug fixes
EthanFennell Mar 17, 2025
5125915
Moved vernacular query to page.js, simplified page.svelte
EthanFennell Mar 17, 2025
576c384
Revert to threshold
EthanFennell Mar 17, 2025
ed7c674
Fixed lazy loading glitches on firefox
EthanFennell Mar 23, 2025
c903782
Fixed sqlite fetch issue
EthanFennell Mar 24, 2025
ce721f4
Add hyperlinks to headwords in XML
MrCars0n Mar 28, 2025
d7f0512
Remove unused variable and comments
MrCars0n Mar 28, 2025
22e24db
show single entry styles
AslanRules Mar 31, 2025
02a0649
Added stores. Refactored lexicon code. Included reversal/vernacular m…
EthanFennell Apr 2, 2025
244e66b
Merge and formatting
EthanFennell Apr 4, 2025
e799792
Applied suggestions
EthanFennell Apr 4, 2025
68f458c
Small changes
EthanFennell Apr 4, 2025
d357369
Small changes
EthanFennell Apr 4, 2025
c5f1d6a
miscellaneous small refactors
AslanRules Apr 4, 2025
3200ce1
Format
EthanFennell Apr 7, 2025
b96dfeb
Fix test
EthanFennell Apr 9, 2025
39a93ae
Fix accessibility issues
aidanpscott Apr 9, 2025
b1d01f4
Add fallback for summary without matches
MrCars0n Apr 9, 2025
3c6fb6c
Fix comma issue. Fix duplicate listeners
EthanFennell Apr 9, 2025
e1b9319
Add proper type definition for vernacularWordsStore
MrCars0n Apr 9, 2025
89234a1
Improve store definitions
MrCars0n Apr 9, 2025
5a90e8b
Vernacular word hyperlink fix
MrCars0n Apr 9, 2025
8f48be7
Fix lint issues
chrisvire Apr 10, 2025
aba7dfe
Fix language tab to match native app
aidanpscott Apr 10, 2025
a024a3a
Remove padding
MrCars0n Apr 10, 2025
83f7217
Applied feedback for language tabs
EthanFennell Apr 11, 2025
6ba5dc1
fix lint
chrisvire Apr 11, 2025
d862db3
Fix spacing
EthanFennell Apr 11, 2025
b29397e
Adjust word list spacing
aidanpscott Apr 11, 2025
b8d2c7f
Fix navbar hiding on scroll and div organization
MrCars0n Apr 13, 2025
25e5218
Fix more div organizaiton
MrCars0n Apr 13, 2025
57175da
Spacing fix
MrCars0n Apr 13, 2025
9c2e9bb
Implement lexicon error handling
aidanpscott Apr 14, 2025
becc3cf
Implement fetch logic for reversal view
aidanpscott Apr 14, 2025
fde38eb
Fix a potential security vulnerability
aidanpscott Apr 14, 2025
41fe9ae
fix lint
chrisvire Apr 14, 2025
e18e1d3
Remove hardcoded colors
aidanpscott Apr 15, 2025
90f420e
Split LexiconReversalListView into separate components.
chrisvire Apr 16, 2025
c8959ae
Remove hardcoded color
aidanpscott Apr 16, 2025
059d048
Remove alphabetStrip artifact
MrCars0n Apr 16, 2025
56b7def
Add proper reversal file fetch
aidanpscott Apr 16, 2025
c975d8b
Remove phantom endpoint call
MrCars0n Apr 16, 2025
89ea8e6
Add grid view
MrCars0n Apr 16, 2025
e5fe311
Remove HEAD request in file loading
aidanpscott Apr 16, 2025
220fbba
Remove unnecessary comments
aidanpscott Apr 16, 2025
0365a9a
Add grid view
MrCars0n Apr 16, 2025
a1a5701
Add grid view
MrCars0n Apr 16, 2025
3c3e224
Remove redundancy
aidanpscott Apr 16, 2025
c072845
convertReversalIndex create index.json
chrisvire Apr 16, 2025
1711d25
Use ReversalIndex to load reversal files
chrisvire Apr 16, 2025
7518a06
Fix wide screen gap
MrCars0n Apr 17, 2025
69166fa
Draft one of search
Christopher-Shiu Mar 24, 2025
9f7ff28
Merge branch 'main' into feature/search/683
EthanFennell Apr 23, 2025
131b388
duplicate import
EthanFennell Apr 23, 2025
84e403e
Update src/lib/components/LexiconXMLView.svelte
Christopher-Shiu Apr 23, 2025
44801f0
Add container style and xml backgorund color
MrCars0n Apr 24, 2025
72a1027
Replac hardcoded colors
aidanpscott Apr 25, 2025
54be2e0
Add background colors for view
aidanpscott Apr 25, 2025
ce111cb
Fix background color sty;es
aidanpscott Apr 25, 2025
921b67a
Fix xml view background color
aidanpscott Apr 25, 2025
ffb2733
Implement full DAB styles
aidanpscott Apr 26, 2025
0b11d66
Background color typo
MrCars0n Apr 26, 2025
24ff96b
Add grid view
MrCars0n Apr 16, 2025
8e7ee4c
Display Lexicon Views
aidanpscott Apr 18, 2025
b081ea2
duplicate import
EthanFennell Apr 23, 2025
7f89651
Add container style and xml backgorund color
MrCars0n Apr 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,6 @@
"node": "20.9.0"
},
"dependencies": {
"sql.js": "^1.12.0"
"sql.js": "^1.13.0"
}
}
25 changes: 25 additions & 0 deletions src/lib/components/AlphabetStrip.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script lang="ts">
export let alphabet: string[];
export let activeLetter: string;
export let onLetterSelect: (letter: string) => void;
</script>

<div
class="flex m-2 gap-1 md:gap-2 mb-4 justify-start overflow-x-auto whitespace-nowrap pb-2 snap-x min-w-[100vw]"
style="background-color: var(--TabBackgroundColor);"
>
{#each alphabet as letter}
<button
class="px-3 py-2 text-sm font-bold border rounded-md cursor-pointer snap-start
sm:px-4 sm:py-3 sm:text-base
md:px-5 md:py-4 md:text-base
lg:px-6 lg:py-4 lg:text-lg"
style={activeLetter === letter
? 'background-color: var(--TitleBackgroundColor); border-color: var(--PrimaryColor); color: var(--TextColor1);'
: 'background-color: var(--BackgroundColor); color: var(--TabTextColor); border-color: var(--SettingsSeparatorColor); hover:background-color: var(--TextHighlightColor);'}
on:click={() => onLetterSelect(letter)}
>
{letter}
</button>
{/each}
</div>
204 changes: 204 additions & 0 deletions src/lib/components/LexiconEntryView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,207 @@
</script>

<pre class="p-4 whitespace-pre-wrap break-words min-w-[100vw]">{@html xmlData}</pre>

<script>
import { base } from '$app/paths';
import config from '$lib/data/config';
import { convertStyle } from '$lib/data/stores';
import initSqlJs from 'sql.js';
import { afterUpdate, onMount } from 'svelte';

export let selectedWord;
export let vernacularWordsList;
export let vernacularLanguage;
export let onSelectWord;
export let onSwitchLanguage;

let xmlData = '';

let singleEntryStyles = config.singleEntryStyles;

async function queryXmlByWordId(wordId) {
try {
const SQL = await initSqlJs({
locateFile: (file) => `${base}/wasm/sql-wasm.wasm`
});

const response = await fetch(`${base}/data.sqlite`);
if (!response.ok) {
throw new Error(
`Failed to fetch database: ${response.status} ${response.statusText}`
);
}
const buffer = await response.arrayBuffer();
const db = new SQL.Database(new Uint8Array(buffer));
if (!db) {
console.error('Database not initialized');
return null;
}

const stmt = db.prepare('SELECT xml FROM entries WHERE id = ?');
stmt.bind([wordId]);

let result = null;
if (stmt.step()) {
result = stmt.getAsObject().xml;
}
stmt.free();
db.close();

return result;
} catch (error) {
console.error(`Error querying XML for word ID ${wordId}:`, error);
return null;
}
}

function formatXmlByClass(xmlString) {
if (!xmlString) return '';

const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');

// Check if parsing failed
const parseError = xmlDoc.querySelector('parsererror');
if (parseError) {
console.error('XML parsing error:', parseError.textContent);
return `<span class="text-error" style="color: var(--TextColor6);">Error parsing XML: Invalid format</span>`;
}

function processNode(node, parentHasSenseNumber = false) {
let output = '';

if (node.nodeType === Node.TEXT_NODE) {
return node.nodeValue.trim() ? node.nodeValue + ' ' : '';
}

if (node.nodeType === Node.ELEMENT_NODE) {
let className = node.getAttribute('class') || '';
let isSenseNumber = className.includes('sensenumber');

let parentContainsSenseNumber =
parentHasSenseNumber ||
[...node.parentNode.children].some(
(child) =>
child.getAttribute &&
(child.getAttribute('class') || '').includes('sensenumber')
);

if (node.tagName === 'a' && node.hasAttribute('href')) {
const href = node.getAttribute('href');
const match = href.match(/E-(\d+)/); // Extract index number
if (match) {
const index = parseInt(match[1], 10); // Extracted number as integer
const wordObject = vernacularWordsList.find((item) => item.id === index);
const word = wordObject ? wordObject.name : 'Unknown'; // Fallback if not found
const homonymIndex = wordObject ? wordObject.homonym_index : 1; // Default to 1 if not found

let linkText = node.textContent.trim();

// If the text inside the link matches the homonym index, use the homonym index as the text
if (linkText === String(homonymIndex)) {
linkText = homonymIndex.toString();
}

output += `<span class="clickable cursor-pointer" style="color: var(--LinkColor); text-decoration: underline;" data-word="${word}" data-index="${index}" data-homonym="${homonymIndex}">${linkText}</span>`;
return output;
}
} else {
output += '<' + node.tagName;
for (let attr of node.attributes) {
output += ` ${attr.name}="${attr.value}"`;
}

// I've added appropriate styling based on class name
if (className.includes('sensenumber')) {
output += ` style="color: var(--TextColor1); font-weight: bold;"`;
} else if (className.includes('vernacular')) {
output += ` style="color: var(--TextColor2);"`;
} else if (className.includes('example')) {
output += ` style="color: var(--TextColor3); font-style: italic;"`;
} else if (className.includes('definition')) {
output += ` style="color: var(--TextColor); font-weight: normal;"`;
}

output += '>';

for (let child of node.childNodes) {
output += processNode(child, parentContainsSenseNumber || isSenseNumber);
}

output += `</${node.tagName}>`;
}
}

return output;
}

return processNode(xmlDoc.documentElement);
}

async function updateXmlData() {
if (
!selectedWord ||
(!selectedWord.index && (!selectedWord.indexes || selectedWord.indexes.length === 0))
) {
xmlData = '';
return;
}

let wordIds = selectedWord.indexes ? selectedWord.indexes : [selectedWord.index];
let xmlResults = await Promise.all(wordIds.map(queryXmlByWordId));

// Insert an `<hr>` tag or a visible separator between entries
xmlData =
xmlResults
.filter((xml) => xml) // Ensure no null values are included
.map(formatXmlByClass)
.join('\n<hr style="border-color: var(--SettingsSeparatorColor);">\n') +
'\n<hr style="border-color: var(--SettingsSeparatorColor);">\n';
}

function attachEventListeners() {
const spans = document.querySelectorAll('.clickable');

spans.forEach((span) => {
const oldSpan = span.cloneNode(true);
span.parentNode.replaceChild(oldSpan, span);
});

const freshSpans = document.querySelectorAll('.clickable');
freshSpans.forEach((span) => {
span.addEventListener('click', () => {
onSwitchLanguage(vernacularLanguage);
const word = span.getAttribute('data-word');
const index = parseInt(span.getAttribute('data-index'), 10);
const homonym_index = parseInt(span.getAttribute('data-homonym'), 10);

onSelectWord({
word,
index,
homonym_index
});
});
});
}

function applyStyles() {
for (let stl of singleEntryStyles) {
for (let elm of document.querySelectorAll(stl.name)) {
elm.style = convertStyle(stl.properties);
}
}
}

onMount(updateXmlData);

afterUpdate(() => {
updateXmlData();
applyStyles();
attachEventListeners();
});
</script>

<pre
class="p-4 whitespace-pre-wrap break-words min-w-[100vw]"
style="background-color: var(--BackgroundColor); color: var(--TextColor);">{@html xmlData}</pre>
11 changes: 7 additions & 4 deletions src/lib/components/LexiconReversalListView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
export let onSelectWord;
</script>

<ul class="space-y-3 px-4 pb-4">
<ul class="space-y-3 px-4 pb-4" style="background-color: var(--BackgroundColor);">
{#each reversalWordsList as { word, indexes, vernacularWords, letter }}
<li class="cursor-pointer text-lg mb-3" id="letter-{letter}">
<button
type="button"
class="w-full text-left py-1"
aria-label={`Select word ${word}`}
style="color: var(--TextColor); border-bottom: 1px solid var(--SettingsSeparatorColor);"
on:click={() => onSelectWord({ word, indexes })}
on:keydown={(event) => {
if (event.key === 'Enter' || event.key === ' ') {
Expand All @@ -18,12 +19,14 @@
}
}}
>
<p class="font-bold break-words">{word}</p>
<p class="text-md ml-4">
<p class="font-bold break-words" style="color: var(--TextColor);">{word}</p>
<p class="text-md ml-4" style="color: var(--TextColor);">
{#each vernacularWords as { name, homonymIndex }, i}
{#if i > 0},
{/if}
{name}{#if homonymIndex > 0}<sub>{homonymIndex}</sub>{/if}
<span style="color: var(--TextColor);"
>{name}{#if homonymIndex > 0}<sub>{homonymIndex}</sub>{/if}</span
>
{/each}
</p>
</button>
Expand Down
35 changes: 35 additions & 0 deletions src/lib/components/LexiconReversalView.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script>
import AlphabetStrip from './AlphabetStrip.svelte';
import LexiconLanguageTabs from './LexiconLanguageTabs.svelte';

export let alphabet = [];
export let selectedLanguage;
export let vernacularLanguage;
export let reversalLanguage;
export let selectedLetter;
export let onSwitchLanguage;
export let onLetterChange;

let currentLetter = alphabet[0];

async function handleLetterSelect(letter) {
currentLetter = letter;
onLetterChange(letter);
}

$: if (alphabet && alphabet.length > 0) {
currentLetter = alphabet[0];
}
$: if (selectedLetter !== currentLetter) {
currentLetter = selectedLetter;
}
</script>

<LexiconLanguageTabs
{reversalLanguage}
{selectedLanguage}
{onSwitchLanguage}
{vernacularLanguage}
/>

<AlphabetStrip {alphabet} activeLetter={currentLetter} onLetterSelect={handleLetterSelect} />
7 changes: 4 additions & 3 deletions src/lib/components/LexiconVernacularListView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
export let onSelectWord;
</script>

<ul class="space-y-3 px-4 pb-4">
<ul class="space-y-3 px-4 pb-4" style="background-color: var(--BackgroundColor);">
{#each vernacularWordsList as { id, name, homonym_index, type, num_senses, summary, letter }}
<li class="cursor-pointer text-lg mb-3 scroll-mt-16" id="letter-{letter}">
<button
type="button"
class="w-full text-left py-1"
aria-label={`Select word ${name}`}
style="color: var(--TextColor); border-bottom: 1px solid var(--SettingsSeparatorColor);"
on:click={() => onSelectWord({ word: name, index: id })}
on:keydown={(event) => {
if (event.key === 'Enter' || event.key === ' ') {
Expand All @@ -18,11 +19,11 @@
}
}}
>
<p class="font-bold break-words">
<p class="font-bold break-words" style="color: var(--TextColor);">
{name}{#if homonym_index > 0}<sub>{homonym_index}</sub>{/if}
</p>
{#if summary}
<p class="ml-4 italic">
<p class="ml-4 italic" style="color: var(--TextColor2);">
{#each summary.match(/{(.*?)}/g) || [] as match}
{match.replace(/[{}]/g, '')}
{/each}
Expand Down
Loading
Loading