2019-05-25 02:50:31 +02:00
import md from 'marked' ;
import { removeTags , slugify } from '../../helpers' ;
2019-06-06 23:41:30 +02:00
import { getWordsStats , getHomonymnNumber } from './utilities' ;
2019-06-06 19:03:00 +02:00
import { getMatchingSearchWords , highlightSearchTerm , getSearchFilters , getSearchTerm } from './search' ;
import { showSection } from './displayToggles' ;
2019-05-25 02:50:31 +02:00
import { setupSearchFilters , setupInfoModal } from './setupListeners' ;
2019-06-06 19:03:00 +02:00
import { parseReferences } from './wordManagement' ;
2019-06-04 19:11:58 +02:00
import { renderAd } from '../ads' ;
2019-06-06 19:47:21 +02:00
import { sortWords } from './wordManagement' ;
2019-05-25 02:50:31 +02:00
export function renderAll ( ) {
2019-05-31 21:15:14 +02:00
renderTheme ( ) ;
2019-05-25 02:50:31 +02:00
renderDictionaryDetails ( ) ;
renderPartsOfSpeech ( ) ;
2019-06-06 19:47:21 +02:00
sortWords ( ) ;
2019-05-25 02:50:31 +02:00
renderWords ( ) ;
}
2019-06-06 19:03:00 +02:00
export function renderTheme ( ) {
const { theme } = window . currentDictionary . settings ;
document . body . id = theme + 'Theme' ;
}
2019-05-25 02:50:31 +02:00
export function renderDictionaryDetails ( ) {
renderName ( ) ;
2019-07-07 06:20:06 +02:00
showSection ( 'description' ) ;
2019-05-25 02:50:31 +02:00
}
export function renderName ( ) {
const dictionaryName = removeTags ( window . currentDictionary . name ) + ' ' + removeTags ( window . currentDictionary . specification ) ;
document . getElementById ( 'dictionaryName' ) . innerHTML = dictionaryName ;
2019-05-30 22:01:34 +02:00
const shareLink = window . location . pathname . match ( new RegExp ( window . currentDictionary . externalID + '$' ) ) ? window . location . pathname
: window . location . pathname . substring ( 0 , window . location . pathname . indexOf ( window . currentDictionary . externalID ) ) + window . currentDictionary . externalID ;
document . getElementById ( 'dictionaryShare' ) . href = shareLink ;
2019-05-25 02:50:31 +02:00
}
export function renderDescription ( ) {
const descriptionHTML = md ( removeTags ( window . currentDictionary . description ) ) ;
document . getElementById ( 'detailsPanel' ) . innerHTML = '<div class="content">' + descriptionHTML + '</div>' ;
}
export function renderDetails ( ) {
const { partsOfSpeech , alphabeticalOrder } = window . currentDictionary ;
2019-07-07 06:20:06 +02:00
const { phonology , phonotactics , orthography , grammar } = window . currentDictionary . details ;
const partsOfSpeechHTML = ` <p><strong>Parts of Speech:</strong></p><div> ${ partsOfSpeech . map ( partOfSpeech => '<span class="tag">' + partOfSpeech + '</span>' ) . join ( ' ' ) } </div> ` ;
const alphabeticalOrderHTML = ` <p><strong>Alphabetical Order:</strong></p><div> ${
2019-05-25 02:50:31 +02:00
( alphabeticalOrder . length > 0 ? alphabeticalOrder : [ 'English Alphabet' ] ) . map ( letter => ` <span class="tag"> ${ letter } </span> ` ) . join ( ' ' )
2019-07-07 06:20:06 +02:00
} < / d i v > ` ;
2019-05-25 02:50:31 +02:00
const generalHTML = ` <h3>General</h3> ${ partsOfSpeechHTML } ${ alphabeticalOrderHTML } ` ;
2019-07-07 06:20:06 +02:00
const { consonants , vowels , blends } = phonology
const consonantHTML = ` <p><strong>Consonants:</strong></p><div> ${ consonants . map ( letter => ` <span class="tag"> ${ letter } </span> ` ) . join ( ' ' ) } </div> ` ;
const vowelHTML = ` <p><strong>Vowels:</strong></p><div> ${ vowels . map ( letter => ` <span class="tag"> ${ letter } </span> ` ) . join ( ' ' ) } </div> ` ;
const blendHTML = blends . length > 0 ? ` <p><strong>Polyphthongs / Blends:</strong></p><div> ${ blends . map ( letter => ` <span class="tag"> ${ letter } </span> ` ) . join ( ' ' ) } </p> ` : '' ;
2019-05-25 02:50:31 +02:00
const phonologyHTML = ` <h3>Phonology</h3>
< div class = "split two" >
< div > $ { consonantHTML } < / d i v >
< div > $ { vowelHTML } < / d i v >
< / d i v >
$ { blendHTML } ` ;
2019-07-07 06:20:06 +02:00
const { onset , nucleus , coda } = phonotactics ;
const onsetHTML = ` <p><strong>Onset:</strong></p><div> ${ onset . map ( letter => ` <span class="tag"> ${ letter } </span> ` ) . join ( ' ' ) } </div> ` ;
const nucleusHTML = ` <p><strong>Nucleus:</strong></p><div> ${ nucleus . map ( letter => ` <span class="tag"> ${ letter } </span> ` ) . join ( ' ' ) } </div> ` ;
const codaHTML = ` <p><strong>Coda:</strong></p><div> ${ coda . map ( letter => ` <span class="tag"> ${ letter } </span> ` ) . join ( ' ' ) } </div> ` ;
const phonotacticsNotesHTML = phonotactics . notes . trim ( ) . length > 0 ? '<p><strong>Notes:</strong></p><div>' + md ( removeTags ( phonotactics . notes ) ) + '</div>' : '' ;
2019-05-25 02:50:31 +02:00
const phonotacticsHTML = ` <h3>Phonotactics</h3>
< div class = "split three" >
< div > $ { onsetHTML } < / d i v >
< div > $ { nucleusHTML } < / d i v >
< div > $ { codaHTML } < / d i v >
< / d i v >
2019-07-07 06:20:06 +02:00
$ { phonotacticsNotesHTML } ` ;
2019-05-25 02:50:31 +02:00
2019-07-07 06:20:06 +02:00
const { translations } = orthography ;
const translationsHTML = ` <p><strong>Translations</strong></p><div> ${ translations . map ( translation => {
translation = translation . split ( '=' ) . map ( value => value . trim ( ) ) ;
if ( translation . length > 1 && translation [ 0 ] !== '' && translation [ 1 ] !== '' ) {
return ` <span><span class="tag"> ${ translation [ 0 ] } </span><span class="tag orthographic-translation"> ${ translation [ 1 ] } </span></span> ` ;
}
return false ;
} ) . filter ( html => html !== false ) . join ( ' ' ) } < / d i v > ` ;
const orthographyNotesHTML = '<p><strong>Notes</strong></p><div>' + md ( removeTags ( orthography . notes ) ) + '</div>' ;
const orthographyHTML = ` <h3>Orthography</h3>
$ { translations . length > 0 ? translationsHTML : '' }
$ { orthographyNotesHTML } ` ;
const grammarHTML = '<h3>Grammar</h3><div>' + md ( removeTags ( grammar . notes ) ) + '</div>' ;
2019-05-25 02:50:31 +02:00
detailsPanel . innerHTML = generalHTML + phonologyHTML + phonotacticsHTML + orthographyHTML + grammarHTML ;
}
export function renderStats ( ) {
const wordStats = getWordsStats ( ) ;
const numberOfWordsHTML = ` <p><strong>Number of Words</strong><br> ${ wordStats . numberOfWords . map ( stat => ` <span><span class="tag"> ${ stat . name } </span><span class="tag"> ${ stat . value } </span></span> ` ) . join ( ' ' ) } </p> ` ;
const wordLengthHTML = ` <p><strong>Word Length</strong><br><span><span class="tag">Shortest</span><span class="tag"> ${ wordStats . wordLength . shortest } </span></span>
< span > < span class = "tag" > Longest < / s p a n > < s p a n c l a s s = " t a g " > $ { w o r d S t a t s . w o r d L e n g t h . l o n g e s t } < / s p a n > < / s p a n >
< span > < span class = "tag" > Average < / s p a n > < s p a n c l a s s = " t a g " > $ { w o r d S t a t s . w o r d L e n g t h . a v e r a g e } < / s p a n > < / s p a n > < / p > ` ;
const letterDistributionHTML = ` <p><strong>Letter Distribution</strong><br> ${ wordStats . letterDistribution . map ( stat => ` <span title=" ${ stat . number } ${ stat . letter } 's total"><span class="tag"> ${ stat . letter } </span><span class="tag"> ${ stat . percentage . toFixed ( 2 ) } </span></span> ` ) . join ( ' ' ) } </p> ` ;
const totalLettersHTML = ` <p><strong> ${ wordStats . totalLetters } Total Letters</strong></p> ` ;
detailsPanel . innerHTML = numberOfWordsHTML + wordLengthHTML + letterDistributionHTML + totalLettersHTML ;
}
export function renderPartsOfSpeech ( onlyOptions = false ) {
let optionsHTML = '<option value=""></option>' ,
searchHTML = '<label>Unclassified <input type="checkbox" checked id="searchPartOfSpeech__None"></label>' ;
window . currentDictionary . partsOfSpeech . forEach ( partOfSpeech => {
partOfSpeech = removeTags ( partOfSpeech ) ;
optionsHTML += ` <option value=" ${ partOfSpeech } "> ${ partOfSpeech } </option> ` ;
searchHTML += ` <label> ${ partOfSpeech } <input type="checkbox" checked id="searchPartOfSpeech_ ${ slugify ( partOfSpeech ) } "></label> ` ;
} ) ;
searchHTML += ` <a class="small button" id="checkAllFilters">Check All</a> <a class="small button" id="uncheckAllFilters">Uncheck All</a> ` ;
Array . from ( document . getElementsByClassName ( 'part-of-speech-select' ) ) . forEach ( select => {
const selectedValue = select . value ;
select . innerHTML = optionsHTML ;
select . value = selectedValue ;
} ) ;
if ( ! onlyOptions ) {
document . getElementById ( 'searchPartsOfSpeech' ) . innerHTML = searchHTML ;
}
setupSearchFilters ( ) ;
}
export function renderWords ( ) {
let wordsHTML = '' ;
let words = false ;
if ( window . currentDictionary . words . length === 0 ) {
wordsHTML = ` <article class="entry">
< header >
< h4 class = "word" > No Words Found < / h 4 >
< / h e a d e r >
< dl >
< dt class = "definition" > Either this dictionary has not yet been started , or something prevented words from downloading . < / d t >
< / d l >
< / a r t i c l e > ` ;
} else {
words = getMatchingSearchWords ( ) ;
if ( words . length === 0 ) {
wordsHTML = ` <article class="entry">
< header >
< h4 class = "word" > No Search Results < / h 4 >
< / h e a d e r >
< dl >
< dt class = "definition" > Edit your search or filter to show words . < / d t >
< / d l >
< / a r t i c l e > ` ;
}
2019-06-04 19:11:58 +02:00
words . forEach ( ( originalWord , displayIndex ) => {
2019-05-25 02:50:31 +02:00
const word = highlightSearchTerm ( {
name : removeTags ( originalWord . name ) ,
pronunciation : removeTags ( originalWord . pronunciation ) ,
partOfSpeech : removeTags ( originalWord . partOfSpeech ) ,
definition : removeTags ( originalWord . definition ) ,
2019-06-04 19:11:58 +02:00
details : parseReferences ( removeTags ( originalWord . details ) ) ,
2019-05-25 02:50:31 +02:00
wordId : originalWord . wordId ,
} ) ;
2019-06-06 23:41:30 +02:00
const homonymnNumber = getHomonymnNumber ( originalWord ) ;
2019-05-30 22:01:34 +02:00
const shareLink = window . location . pathname + ( window . location . pathname . match ( new RegExp ( word . wordId + '$' ) ) ? '' : '/' + word . wordId ) ;
2019-06-04 19:11:58 +02:00
wordsHTML += renderAd ( displayIndex ) ;
2019-05-25 02:50:31 +02:00
wordsHTML += ` <article class="entry" id=" ${ word . wordId } ">
< header >
2019-06-06 23:41:30 +02:00
< h4 class = "word" > $ { word . name } $ { homonymnNumber > 0 ? ' <sub>' + homonymnNumber . toString ( ) + '</sub>' : '' } < / h 4 >
2019-05-25 02:50:31 +02:00
< span class = "pronunciation" > $ { word . pronunciation } < / s p a n >
< span class = "part-of-speech" > $ { word . partOfSpeech } < / s p a n >
2019-05-30 22:01:34 +02:00
< a href = "${shareLink}" target = "_blank" class = "small button word-option-button" title = "Link to Word" > & # 10150 ; < / a >
2019-05-25 02:50:31 +02:00
< / h e a d e r >
< dl >
< dt class = "definition" > $ { word . definition } < / d t >
< dd class = "details" >
$ { md ( word . details ) }
< / d d >
< / d l >
< / a r t i c l e > ` ;
} ) ;
}
document . getElementById ( 'entries' ) . innerHTML = wordsHTML ;
// Show Search Results
const searchTerm = getSearchTerm ( ) ;
const filters = getSearchFilters ( ) ;
let resultsText = searchTerm !== '' || ! filters . allPartsOfSpeechChecked ? ( words ? words . length : 0 ) . toString ( ) + ' Results' : '' ;
resultsText += ! filters . allPartsOfSpeechChecked ? ' (Filtered)' : '' ;
document . getElementById ( 'searchResults' ) . innerHTML = resultsText ;
}
export function renderInfoModal ( content ) {
const modalElement = document . createElement ( 'section' ) ;
modalElement . classList . add ( 'modal' , 'info-modal' ) ;
modalElement . innerHTML = ` <div class="modal-background"></div>
< div class = "modal-content" >
< a class = "close-button" > & times ; & # xFE0E ; < / a >
< section class = "info-modal" >
< div class = "content" >
$ { content }
< / d i v >
< / s e c t i o n >
< / d i v > ` ;
document . body . appendChild ( modalElement ) ;
setupInfoModal ( modalElement ) ;
}