Skip to content

Commit

Permalink
Sort & collapse kanji dictionary entries (#1581)
Browse files Browse the repository at this point in the history
* sort kanji dict

* update test

* collapsible kanji dict

* Refine CSS for kanji collapse + Add doc for custom CSS

* upd css comment

* remove sort by def count
  • Loading branch information
khaitruong922 authored Nov 19, 2024
1 parent 746bed5 commit fd97f0b
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 65 deletions.
78 changes: 52 additions & 26 deletions ext/css/display.css
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@
--animation-duration2: calc(2 * var(--animation-duration));

--collapsible-definition-line-count: 3;
--collapsible-kanji-glyph-data-line-count: 3;
--kanji-glyph-table-header-height: calc((20em / var(--font-size-no-units)) + var(--kanji-glyph-table-cell-padding) * 3);
--collapsible-definition-test-offset: 0.2em;
--collpasible-kanji-glyph-data-test-offset: 0.2em;

/* Colors */
--background-color: #ffffff;
Expand All @@ -127,6 +130,8 @@
--headword-kanji-border-color-popular: var(--headword-kanji-border-color);
--headword-kanji-border-color-rare: var(--headword-kanji-border-color);

--kanji-glyph-table-cell-padding: 0.36em;

--light-border-color: #eeeeee;
--medium-border-color: #dddddd;
--dark-border-color: #777777;
Expand Down Expand Up @@ -1184,14 +1189,6 @@ button.action-button:active {
display: list-item;
position: relative;
}
.definition-item-inner.collapsible.collapsed {
max-height: calc(1em * var(--collapsible-definition-line-count) * var(--line-height));
overflow: hidden;
}
.definition-item-inner.collapse-test {
max-height: calc(1em * var(--collapsible-definition-line-count) * var(--line-height) + var(--collapsible-definition-test-offset));
overflow: hidden;
}
.definition-item-inner {
display: flex;
flex-flow: row nowrap;
Expand All @@ -1202,7 +1199,9 @@ button.action-button:active {
background-color: transparent;
transition: background-color var(--animation-duration) ease-in-out;
}
button.definition-item-expansion-button {

/* Collapse & Expand */
button.expansion-button {
--button-content-color: var(--text-color-light4);
--button-border-color: transparent;
--button-background-color: transparent;
Expand All @@ -1223,34 +1222,57 @@ button.definition-item-expansion-button {
border-radius: 0;
border: 0;
}
.definition-item-inner:not(.collapsible)>button.definition-item-expansion-button {
display: none;
}
button.definition-item-expansion-button:hover+.definition-item-content,
button.definition-item-expansion-button:active+.definition-item-content,
button.definition-item-expansion-button:focus+.definition-item-content {

button.expansion-button:hover+.definition-item-content,
button.expansion-button:active+.definition-item-content,
button.expansion-button:focus+.definition-item-content,
button.expansion-button:hover+.kanji-glyph-table,
button.expansion-button:active+.kanji-glyph-table,
button.expansion-button:focus+.kanji-glyph-table {
background-color: var(--accent-color-transparent25);
}
button.definition-item-expansion-button:focus:not(:focus-visible)+.definition-item-content {
button.expansion-button:focus:not(:focus-visible)+.definition-item-content,
button.expansion-button:focus:not(:focus-visible)+.kanji-glyph-table {
background-color: transparent;
}
button.definition-item-expansion-button:focus:hover+.definition-item-content,
button.definition-item-expansion-button:focus:active+.definition-item-content,
button.definition-item-expansion-button:focus:focus-visible+.definition-item-content {
button.expansion-button:focus:hover+.definition-item-content,
button.expansion-button:focus:active+.definition-item-content,
button.expansion-button:focus:focus-visible+.definition-item-content,
button.expansion-button:focus:hover+.kanji-glyph-table,
button.expansion-button:focus:active+.kanji-glyph-table,
button.expansion-button:focus:focus-visible+.kanji-glyph-table {
background-color: var(--accent-color-transparent25);
}
.definition-item-expansion-button-icon {
.definition-item-inner.collapsible.collapsed {
max-height: calc(1em * var(--collapsible-definition-line-count) * var(--line-height));
overflow: hidden;
}
.definition-item-inner.collapse-test {
max-height: calc(1em * var(--collapsible-definition-line-count) * var(--line-height) + var(--collapsible-definition-test-offset));
overflow: hidden;
}
.kanji-glyph-data.collapsible.collapsed {
max-height: calc(1em * var(--collapsible-kanji-glyph-data-line-count) * var(--line-height) + var(--kanji-glyph-table-header-height));
overflow: hidden;
}
.kanji-glyph-data.collapse-test {
max-height: calc(1em * var(--collapsible-kanji-glyph-data-line-count) * var(--line-height) + var(--kanji-glyph-table-header-height) + var(--collpasible-kanji-glyph-data-test-offset));
overflow: hidden;
}
:not(.collapsible)>button.expansion-button {
display: none;
}
.expansion-button-icon {
transform: rotate(0deg);
width: calc(16em / var(--font-size-no-units));
height: calc(16em / var(--font-size-no-units));
background-color: var(--button-current-content-color);
transition: background-color var(--animation-duration) ease-in-out;
}
.definition-item-inner.collapsible:not(.collapsed)>button.definition-item-expansion-button>.definition-item-expansion-button-icon {
.collapsible:not(.collapsed)>button.expansion-button>.expansion-button-icon {
transform: rotate(180deg);
}


/* Frequencies */
.frequency-group-item {
display: inline;
Expand Down Expand Up @@ -1515,14 +1537,18 @@ button.definition-item-expansion-button:focus:focus-visible+.definition-item-con
}
.kanji-glyph-data {
margin-top: 0.75em;
display: flex;
flex-flow: row nowrap;
}
.kanji-glyph-table {
border-spacing: 0;
border-collapse: collapse;
}
.kanji-glyph-data>tbody>tr>* {
.kanji-glyph-table>tbody>tr>* {
border-top: var(--thin-border-size) solid var(--medium-border-color);
text-align: left;
vertical-align: top;
padding: 0.36em;
padding: var(--kanji-glyph-table-cell-padding);
margin: 0;
}
.kanji-info-table {
Expand All @@ -1538,11 +1564,11 @@ button.definition-item-expansion-button:focus:focus-visible+.definition-item-con
.kanji-info-table>tbody>tr>td {
text-align: right;
}
.kanji-glyph-data dl {
.kanji-glyph-table dl {
margin-top: 0;
margin-bottom: 1.4em;
}
.kanji-glyph-data dd {
.kanji-glyph-table dd {
margin-left: 0;
}
.kanji-gloss-list {
Expand Down
1 change: 1 addition & 0 deletions ext/js/display/display-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export class DisplayGenerator {
*/
createKanjiEntry(dictionaryEntry) {
const node = this._instantiate('kanji-entry');
node.dataset.dictionary = dictionaryEntry.dictionary;

const glyphContainer = this._querySelector(node, '.kanji-glyph');
const frequencyGroupListContainer = this._querySelector(node, '.frequency-group-list');
Expand Down
21 changes: 16 additions & 5 deletions ext/js/display/element-overflow-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ export class ElementOverflowController {
addElements(entry) {
if (this._dictionaries.size === 0) { return; }

const elements = entry.querySelectorAll('.definition-item-inner');

/** @type {Element[]} */
const elements = [
...entry.querySelectorAll('.definition-item-inner'),
...entry.querySelectorAll('.kanji-glyph-data'),
];
for (const element of elements) {
const {parentNode} = element;
if (parentNode === null) { continue; }
Expand All @@ -96,7 +101,7 @@ export class ElementOverflowController {
element.classList.add('collapsed');
}

const button = element.querySelector('.definition-item-expansion-button');
const button = element.querySelector('.expansion-button');
if (button !== null) {
this._eventListeners.addEventListener(button, 'click', this._onToggleButtonClickBind, false);
}
Expand Down Expand Up @@ -128,9 +133,15 @@ export class ElementOverflowController {
*/
_onToggleButtonClick(e) {
const element = /** @type {Element} */ (e.currentTarget);
const container = element.closest('.definition-item-inner');
if (container === null) { return; }
container.classList.toggle('collapsed');
/** @type {(Element | null)[]} */
const collapsedElements = [
element.closest('.definition-item-inner'),
element.closest('.kanji-glyph-data'),
];
for (const collapsedElement of collapsedElements) {
if (collapsedElement === null) { continue; }
collapsedElement.classList.toggle('collapsed');
}
}

/** */
Expand Down
33 changes: 31 additions & 2 deletions ext/js/language/translator.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,15 @@ export class Translator {
for (const {character, onyomi, kunyomi, tags, definitions, stats, dictionary} of databaseEntries) {
const expandedStats = await this._expandKanjiStats(stats, dictionary);
const dictionaryAlias = this._getDictionaryAlias(dictionary, enabledDictionaryMap);
const dictionaryEntry = this._createKanjiDictionaryEntry(character, dictionary, dictionaryAlias, onyomi, kunyomi, expandedStats, definitions);
const dictionaryEntry = this._createKanjiDictionaryEntry(character, dictionary, dictionaryAlias, onyomi, kunyomi, expandedStats, definitions, enabledDictionaryMap);
dictionaryEntries.push(dictionaryEntry);
tagAggregator.addTags(dictionaryEntry.tags, dictionary, tags);
}

if (dictionaryEntries.length > 1) {
this._sortKanjiDictionaryEntries(dictionaryEntries);
}

await this._addKanjiMeta(dictionaryEntries, enabledDictionaryMap);
await this._expandTagGroupsAndGroup(tagAggregator.getTagExpansionTargets());

Expand Down Expand Up @@ -1533,14 +1537,18 @@ export class Translator {
* @param {string[]} kunyomi
* @param {import('dictionary').KanjiStatGroups} stats
* @param {string[]} definitions
* @param {import('translation').KanjiEnabledDictionaryMap} enabledDictionaryMap
* @returns {import('dictionary').KanjiDictionaryEntry}
*/
_createKanjiDictionaryEntry(character, dictionary, dictionaryAlias, onyomi, kunyomi, stats, definitions) {
_createKanjiDictionaryEntry(character, dictionary, dictionaryAlias, onyomi, kunyomi, stats, definitions, enabledDictionaryMap) {
const {index: dictionaryIndex, priority: dictionaryPriority} = this._getDictionaryOrder(dictionary, enabledDictionaryMap);
return {
type: 'kanji',
character,
dictionary,
dictionaryIndex,
dictionaryAlias,
dictionaryPriority,
onyomi,
kunyomi,
tags: [],
Expand Down Expand Up @@ -2022,6 +2030,27 @@ export class Translator {
databaseEntries.sort(compareFunction);
}

/**
* @param {import('dictionary').KanjiDictionaryEntry[]} dictionaryEntries
*/
_sortKanjiDictionaryEntries(dictionaryEntries) {
/**
* @param {import('dictionary').KanjiDictionaryEntry} v1
* @param {import('dictionary').KanjiDictionaryEntry} v2
* @returns {number}
*/
const compareFunction = (v1, v2) => {
// Sort by dictionary priority
let i = v2.dictionaryPriority - v1.dictionaryPriority;
if (i !== 0) { return i; }

// Sort by dictionary order
i = v1.dictionaryIndex - v2.dictionaryIndex;
return i;
};
dictionaryEntries.sort(compareFunction);
}

/**
* @param {import('translation-internal').TermDictionaryEntry[]} dictionaryEntries
*/
Expand Down
45 changes: 25 additions & 20 deletions ext/templates-display.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
</div></template>
<template id="definition-item-template" data-remove-whitespace-text="true"><li class="definition-item">
<div class="definition-item-inner">
<button type="button" class="definition-item-expansion-button"><div class="definition-item-expansion-button-icon icon" data-icon="double-down-chevron"></div></button>
<button type="button" class="expansion-button"><div class="expansion-button-icon icon" data-icon="double-down-chevron"></div></button>
<div class="definition-item-content">
<div class="definition-tag-list tag-list"></div>
<div class="definition-disambiguation-list"></div>
Expand Down Expand Up @@ -110,7 +110,7 @@
<template id="pronunciation-template"><li class="pronunciation"><span class="pronunciation-tag-list tag-list"></span><span class="pronunciation-disambiguation-list"></span><span class="pronunciation-representation-list"><span class="pronunciation-text-container"></span><span class="pronunciation-downstep-notation-container"></span><span class="pronunciation-graph-container"></span></span></li></template>

<!-- Kanji entry -->
<template id="kanji-entry-template" data-remove-whitespace-text="true"><div class="entry" data-type="kanji">
<template id="kanji-entry-template" data-remove-whitespace-text="true"><div class="entry kanji-entry" data-type="kanji">
<div class="entry-current-indicator" title="Current entry"><span class="entry-current-indicator-inner"></span></div>
<div class="entry-header">
<div class="actions">
Expand Down Expand Up @@ -138,24 +138,29 @@
<div class="entry-body-section-content frequency-group-list"></div>
</div>
</div>
<table class="kanji-glyph-data"><tbody>
<tr>
<th scope="col">Meaning</th>
<th scope="col">Readings</th>
<th scope="col">Statistics</th>
</tr>
<tr>
<td class="kanji-gloss-container"><ol class="kanji-gloss-list"></ol></td>
<td class="kanji-readings"><dl class="kanji-readings-chinese"></dl><dl class="kanji-readings-japanese"></dl></td>
<td class="kanji-statistics"></td>
</tr>
<tr><th scope="col" colspan="3">Classifications</th></tr>
<tr><td colspan="3" class="kanji-classifications"></td></tr>
<tr><th scope="col" colspan="3">Codepoints</th></tr>
<tr><td colspan="3" class="kanji-codepoints"></td></tr>
<tr><th scope="col" colspan="3">Dictionary Indices</th></tr>
<tr><td colspan="3" class="kanji-dictionary-indices"></td></tr>
</tbody></table>
<div class="kanji-glyph-data">
<button type="button" class="expansion-button"><div class="expansion-button-icon icon" data-icon="double-down-chevron"></div></button>
<table class="kanji-glyph-table">
<tbody>
<tr>
<th scope="col">Meaning</th>
<th scope="col">Readings</th>
<th scope="col">Statistics</th>
</tr>
<tr>
<td class="kanji-gloss-container"><ol class="kanji-gloss-list"></ol></td>
<td class="kanji-readings"><dl class="kanji-readings-chinese"></dl><dl class="kanji-readings-japanese"></dl></td>
<td class="kanji-statistics"></td>
</tr>
<tr><th scope="col" colspan="3">Classifications</th></tr>
<tr><td colspan="3" class="kanji-classifications"></td></tr>
<tr><th scope="col" colspan="3">Codepoints</th></tr>
<tr><td colspan="3" class="kanji-codepoints"></td></tr>
<tr><th scope="col" colspan="3">Dictionary Indices</th></tr>
<tr><td colspan="3" class="kanji-dictionary-indices"></td></tr>
</tbody>
</table>
</div>
</div></template>
<template id="kanji-info-table-template"><table class="kanji-info-table"><tbody class="kanji-info-table-body"></tbody></table></template>
<template id="kanji-info-table-item-template"><tr class="kanji-info-table-item"><th scope="col" class="kanji-info-table-item-header"></th><td class="kanji-info-table-item-value"></td></tr></template>
Expand Down
34 changes: 22 additions & 12 deletions ext/templates-modals.html
Original file line number Diff line number Diff line change
Expand Up @@ -548,20 +548,30 @@ <h1 class="modal-title">Pronunciation Dictionaries</h1>
the value can be a unitless integer or decimal number.
</p>
<div class="code margin-above">/* Globally set the line count */
:root {
--collapsible-definition-line-count: 2;
}
:root {
--collapsible-definition-line-count: 2;
}
:root {
--collapsible-kanji-glyph-data-line-count: 2;
}

/* Set the line count for a specific dictionary */
.definition-item[data-dictionary='JMdict'] {
--collapsible-definition-line-count: 2;
}
/* Set the line count for a specific dictionary */
.definition-item[data-dictionary='JMdict'] {
--collapsible-definition-line-count: 2;
}
.kanji-entry[data-dictionary='KANJIDIC'] {
--collapsible-kanji-glyph-data-line-count: 2;
}

/* Spoiler-like functionality, use with <em>Force collapsed</em> mode */
.definition-item[data-dictionary='JMdict'] .definition-item-inner.collapsible.collapsed {
color: #000000;
background-color: #000000;
}
/* Spoiler-like functionality, use with <em>Force collapsed</em> mode */
.definition-item[data-dictionary='JMdict'] .definition-item-inner.collapsible.collapsed {
color: #000000;
background-color: #000000;
}
.kanji-entry[data-dictionary='KANJIDIC'] .kanji-glyph-data.collapsible.collapsed {
color: #000000;
background-color: #000000;
}
</div>
</div>
<div class="modal-footer">
Expand Down
2 changes: 2 additions & 0 deletions test/anki-template-renderer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ describe('AnkiTemplateRenderer', () => {
type: 'kanji',
character: 'c',
dictionary: 'dictionary',
dictionaryIndex: 0,
dictionaryAlias: 'dictionaryAlias',
dictionaryPriority: 0,
onyomi: [],
kunyomi: [],
tags: [],
Expand Down
Loading

0 comments on commit fd97f0b

Please sign in to comment.