Compare commits
11 Commits
b50da238ae
...
bfeea0da55
Author | SHA1 | Date |
---|---|---|
Robbie Antenesse | bfeea0da55 | |
Robbie Antenesse | 602a5a136f | |
Robbie Antenesse | ca43c05b60 | |
Robbie Antenesse | ca1bb63295 | |
Robbie Antenesse | f545f5c786 | |
Robbie Antenesse | 47964bcd53 | |
Robbie Antenesse | 7221a094bc | |
Robbie Antenesse | b4687cd992 | |
Robbie Antenesse | cbe1099a5c | |
Robbie Antenesse | d820aa87cc | |
Robbie Antenesse | afea58de6a |
|
@ -7,7 +7,7 @@
|
|||
<title>Lexiconga</title>
|
||||
<script src="src/index.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<body id="defaultTheme">
|
||||
<header id="top">
|
||||
<h1 id="title">Lexiconga</h1>
|
||||
|
||||
|
@ -136,7 +136,7 @@
|
|||
<a href="https://blog.lexicon.ga" target="_blank" class="small button">Blog</a>
|
||||
<a href="https://github.com/Alamantus/Lexiconga/issues" target="_blank" class="small button">Issues</a>
|
||||
<a href="https://github.com/Alamantus/Lexiconga/releases" target="_blank" class="small button">Updates</a>
|
||||
|
|
||||
<span class="separator">|</span>
|
||||
<a class="button" id="helpInfoButton">Help</a>
|
||||
<a class="button" id="termsInfoButton">Terms</a>
|
||||
<a class="button" id="privacyInfoButton">Privacy</a>
|
||||
|
@ -162,8 +162,8 @@
|
|||
</label>
|
||||
|
||||
<label>Theme
|
||||
<select disabled>
|
||||
<option selected value="default">Default</option>
|
||||
<select id="settingsTheme">
|
||||
<option value="default">Default</option>
|
||||
<option value="dark">Dark</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="blue">Blue</option>
|
||||
|
|
|
@ -57,6 +57,7 @@ export const DEFAULT_DICTIONARY = {
|
|||
export const DEFAULT_SETTINGS = {
|
||||
useIPAPronunciationField: true,
|
||||
useHotkeys: true,
|
||||
theme: 'default',
|
||||
};
|
||||
|
||||
export const DEFAULT_PAGE_SIZE = 50;
|
||||
|
|
|
@ -9,17 +9,17 @@ that allow you to type any IPA symbol with only a standard keyboard.</p>
|
|||
<li>
|
||||
<p>Many symbols that look similar to letters of the English alphabet (such as
|
||||
small caps) can be produced by doubling the capital letter:</p>
|
||||
<pre><code> GG -> ɢ ?? -> ʔ NN -> ɴ BB -> ʙ RR -> ʀ XX -> χ
|
||||
LL -> ʟ II -> ɪ YY -> ʏ UU -> ʊ EE -> ɛ OO -> ɞ
|
||||
AA -> ɑ '' -> ˈ ,, -> ˌ :: -> ː
|
||||
<pre><code> GG → ɢ ?? → ʔ NN → ɴ BB → ʙ RR → ʀ XX → χ
|
||||
LL → ʟ II → ɪ YY → ʏ UU → ʊ EE → ɛ OO → ɞ
|
||||
AA → ɑ '' → ˈ ,, → ˌ :: → ː
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>
|
||||
<p>The slash is used to "reflect," "rotate," or otherwise flip around a given
|
||||
symbol:</p>
|
||||
<pre><code> ʀ/ -> ʁ ʔ/ -> ʕ ?/ -> ʕ r/ -> ɹ y/ -> ʎ m/ -> ɯ
|
||||
o/ -> ø e/ -> ə ɛ/ -> ɜ c/ -> ɔ a/ -> ɐ ɑ/ -> ɒ
|
||||
w/ -> ʍ h/ -> ɥ k/ -> ʞ !/ -> ¡ v/ -> ʌ
|
||||
<pre><code> ʀ/ → ʁ ʔ/ → ʕ ?/ → ʕ r/ → ɹ y/ → ʎ m/ → ɯ
|
||||
o/ → ø e/ → ə ɛ/ → ɜ c/ → ɔ a/ → ɐ ɑ/ → ɒ
|
||||
w/ → ʍ h/ → ɥ k/ → ʞ !/ → ¡ v/ → ʌ
|
||||
</code></pre>
|
||||
<p>Also note that for any digraph, if either of the two characters that
|
||||
compose it are not "standard" letters you can find on your keyboard, the
|
||||
|
@ -35,26 +35,26 @@ visual <code>o|</code> and <code>|o</code>.</p>
|
|||
characters, or two characters next to each other. This includes "hooked"
|
||||
letters (such as ŋ), produced with the original letter and a comma, and
|
||||
"stroked" letters (such as ɟ), produced with the original letter and a dash:</p>
|
||||
<pre><code> m, -> ɱ n, -> ŋ ŋ, -> ɲ v, -> ⱱ c, -> ç j, -> ʝ
|
||||
x, -> ɣ ɣ, -> χ h, -> ɦ w, -> ɰ
|
||||
<pre><code> m, → ɱ n, → ŋ ŋ, → ɲ v, → ⱱ c, → ç j, → ʝ
|
||||
x, → ɣ ɣ, → χ h, → ɦ w, → ɰ
|
||||
|
||||
j- -> ɟ h- -> ħ l- -> ɬ i- -> ɨ u- -> ʉ e- -> ɘ
|
||||
o- -> ɵ ʕ- -> ʢ ?- -> ʡ ʔ- -> ʡ
|
||||
j- → ɟ h- → ħ l- → ɬ i- → ɨ u- → ʉ e- → ɘ
|
||||
o- → ɵ ʕ- → ʢ ?- → ʡ ʔ- → ʡ
|
||||
|
||||
LZ -> ɮ OX -> ɤ XO -> ɤ OE -> œ EB -> ɞ AE -> æ
|
||||
CE -> ɶ RL -> ɺ LR -> ɺ ɾl -> ɺ lɾ -> ɺ
|
||||
LZ → ɮ OX → ɤ XO → ɤ OE → œ EB → ɞ AE → æ
|
||||
CE → ɶ RL → ɺ LR → ɺ ɾl → ɺ lɾ → ɺ
|
||||
|
||||
w| -> ɰ o/ -> ø ɜ( -> ɞ /\ -> ʌ o| -> ɑ a| -> ɑ
|
||||
|o -> ɒ |a -> ɒ
|
||||
w| → ɰ o/ → ø ɜ( → ɞ /\ → ʌ o| → ɑ a| → ɑ
|
||||
|o → ɒ |a → ɒ
|
||||
|
||||
o. -> ʘ |= -> ǂ || -> ‖ /^ -> ↗ /> -> ↗ \v -> ↘
|
||||
\> -> ↘
|
||||
o. → ʘ |= → ǂ || → ‖ /^ → ↗ /> → ↗ \v → ↘
|
||||
\> → ↘
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>
|
||||
<p>Others are based on pronunciation:</p>
|
||||
<pre><code> PH -> ɸ BH -> β TH -> θ DH -> ð SH -> ʃ ZH -> ʒ
|
||||
SJ -> ɕ ZJ -> ʑ ʃx -> ɧ xʃ -> ɧ
|
||||
<pre><code> PH → ɸ BH → β TH → θ DH → ð SH → ʃ ZH → ʒ
|
||||
SJ → ɕ ZJ → ʑ ʃx → ɧ xʃ → ɧ
|
||||
</code></pre>
|
||||
<p>It may be worth noting at this point that digraphs of two lowercase letters
|
||||
were intentionally avoided to prevent interference with regular typing. If
|
||||
|
@ -66,7 +66,7 @@ to the second character.</p>
|
|||
</li>
|
||||
<li>
|
||||
<p>A few digraphs are based on shape:</p>
|
||||
<pre><code> rO -> ɾ r0 -> ɾ vO -> ʋ v0 -> ʋ
|
||||
<pre><code> rO → ɾ r0 → ɾ vO → ʋ v0 → ʋ
|
||||
</code></pre>
|
||||
<p>Another related point: digraphs that contain a lowercase letter can also be
|
||||
typed with that letter as uppercase. So, if <code>RO</code> is easier to type than
|
||||
|
@ -75,35 +75,35 @@ typed with that letter as uppercase. So, if <code>RO</code> is easier to type th
|
|||
<li>
|
||||
<p>Retroflex and nonpulmonic symbols have their own categories:</p>
|
||||
<pre><code> retroflex: ) looks like the shape of the tongue
|
||||
t) -> ʈ d) -> ɖ n) -> ɳ r) -> ɽ ɾ) -> ɽ s) -> ʂ
|
||||
z) -> ʐ ɹ) -> ɻ l) -> ɭ ɗ) -> ᶑ
|
||||
t) → ʈ d) → ɖ n) → ɳ r) → ɽ ɾ) → ɽ s) → ʂ
|
||||
z) → ʐ ɹ) → ɻ l) → ɭ ɗ) → ᶑ
|
||||
|
||||
clicks: clicking noise reminiscent of a *
|
||||
o* -> ʘ |* -> ǀ !* -> ǃ =* -> ǁ
|
||||
o* → ʘ |* → ǀ !* → ǃ =* → ǁ
|
||||
|
||||
implosives and ejective marker: direction of airflow
|
||||
b( -> ɓ d( -> ɗ j( -> ʄ ɟ( -> ʄ g( -> ɠ ɢ( -> ʛ
|
||||
ɖ( -> ᶑ ') -> ʼ
|
||||
b( → ɓ d( → ɗ j( → ʄ ɟ( → ʄ g( → ɠ ɢ( → ʛ
|
||||
ɖ( → ᶑ ') → ʼ
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>
|
||||
<p>Superscripts and diacritics that go above the letter use <code>^</code>, diacritics that
|
||||
go below use <code>_</code>, and miscellaneous "moved" symbols
|
||||
use <code><</code> or <code>></code>:</p>
|
||||
<pre><code> ^h -> ʰ ^n -> ⁿ ^m -> ᵐ ^ŋ -> ᵑ ^l -> ˡ ^w -> ʷ
|
||||
^j -> ʲ ^ɥ -> ᶣ ^ʋ -> ᶹ ^ɣ -> ˠ ^ʕ -> ˤ
|
||||
<pre><code> ^h → ʰ ^n → ⁿ ^m → ᵐ ^ŋ → ᵑ ^l → ˡ ^w → ʷ
|
||||
^j → ʲ ^ɥ → ᶣ ^ʋ → ᶹ ^ɣ → ˠ ^ʕ → ˤ
|
||||
|
||||
_| -> ◌̩ ^| -> ◌̍ _o -> ◌̥ ^o -> ◌̊ _v -> ◌̬ ^v -> ◌̌
|
||||
_| → ◌̩ ^| → ◌̍ _o → ◌̥ ^o → ◌̊ _v → ◌̬ ^v → ◌̌
|
||||
|
||||
_^ -> ◌̯ _: -> ◌̤ _~ -> ◌̰ _[ -> ◌̪ _] -> ◌̺ _{ -> ◌̼
|
||||
_+ -> ◌̟ __ -> ◌̠ _) -> ◌̹ _( -> ◌̜ _# -> ◌̻ [] -> ◌̻
|
||||
_^ → ◌̯ _: → ◌̤ _~ → ◌̰ _[ → ◌̪ _] → ◌̺ _{ → ◌̼
|
||||
_+ → ◌̟ __ → ◌̠ _) → ◌̹ _( → ◌̜ _# → ◌̻ [] → ◌̻
|
||||
|
||||
^> -> ◌̚ ^: -> ◌̈ ^x -> ◌̽ ^~ -> ◌̃
|
||||
^> → ◌̚ ^: → ◌̈ ^x → ◌̽ ^~ → ◌̃
|
||||
|
||||
-' -> ˔ _˔ -> ◌̝ -, -> ˕ _˕ -> ◌̞ <| -> ⊣ _⊣ -> ◌̘
|
||||
>| -> ⊢ _⊢ -> ◌̙
|
||||
-' → ˔ _˔ → ◌̝ -, → ˕ _˕ → ◌̞ <| → ⊣ _⊣ → ◌̘
|
||||
>| → ⊢ _⊢ → ◌̙
|
||||
|
||||
~~ -> ◌̴ >r -> ˞
|
||||
~~ → ◌̴ >r → ˞
|
||||
</code></pre>
|
||||
<p>Note that all of these sequences can be flipped in order—that is, <code>^h</code>
|
||||
produces the same thing as <code>h^</code>. This allows usage such as <code>|<_</code> to produce
|
||||
|
@ -111,16 +111,16 @@ produces the same thing as <code>h^</code>. This allows usage such as <code>|<
|
|||
</li>
|
||||
<li>
|
||||
<p>Tonal countours use numbers plus <code>|</code>:</p>
|
||||
<pre><code> 5| -> ˥ 4| -> ˦ 3| -> ˧ 2| -> ˨ 1| -> ˩
|
||||
+| -> ꜛ -| -> ꜜ
|
||||
<pre><code> 5| → ˥ 4| → ˦ 3| → ˧ 2| → ˨ 1| → ˩
|
||||
+| → ꜛ -| → ꜜ
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>
|
||||
<p>Finally, some digraphs simply have unique mnemonics:</p>
|
||||
<pre><code> ː- -> ˑ "chop off" the bottom triangle
|
||||
(( -> ◌͡◌ two parens for a tie that connects 2 chars
|
||||
)) -> ◌͜◌
|
||||
◌͜◌) -> ‿ one more paren to make it a little bit longer
|
||||
<pre><code> ː- → ˑ "chop off" the bottom triangle
|
||||
(( → ◌͡◌ two parens for a tie that connects 2 chars
|
||||
)) → ◌͜◌
|
||||
◌͜◌) → ‿ one more paren to make it a little bit longer
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
|
@ -1,4 +1,4 @@
|
|||
import { renderDictionaryDetails, renderPartsOfSpeech, renderAll } from "./render";
|
||||
import { renderDictionaryDetails, renderPartsOfSpeech, renderAll, renderWords } from "./render";
|
||||
import { removeTags, cloneObject, getTimestampInSeconds, download, slugify } from "../helpers";
|
||||
import { LOCAL_STORAGE_KEY, DEFAULT_DICTIONARY, MIGRATE_VERSION } from "../constants";
|
||||
import { addMessage, getNextId, hasToken } from "./utilities";
|
||||
|
@ -63,7 +63,10 @@ export function saveEditModal() {
|
|||
window.currentDictionary.settings.caseSensitive = document.getElementById('editCaseSensitive').checked;
|
||||
const needsReSort = window.currentDictionary.settings.sortByDefinition !== document.getElementById('editSortByDefinition').checked;
|
||||
window.currentDictionary.settings.sortByDefinition = document.getElementById('editSortByDefinition').checked;
|
||||
|
||||
let needsWordRender = false;
|
||||
if (hasToken()) {
|
||||
needsWordRender = window.currentDictionary.settings.isPublic !== document.getElementById('editIsPublic').checked;
|
||||
window.currentDictionary.settings.isPublic = document.getElementById('editIsPublic').checked;
|
||||
} else {
|
||||
window.currentDictionary.settings.isPublic = false;
|
||||
|
@ -73,8 +76,8 @@ export function saveEditModal() {
|
|||
saveDictionary();
|
||||
renderDictionaryDetails();
|
||||
renderPartsOfSpeech();
|
||||
|
||||
if (needsReSort) {
|
||||
|
||||
if (needsReSort || needsWordRender) {
|
||||
sortWords(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,25 @@ export function renderDictionaryDetails() {
|
|||
|
||||
export function renderName() {
|
||||
const dictionaryName = removeTags(window.currentDictionary.name) + ' ' + removeTags(window.currentDictionary.specification);
|
||||
document.getElementById('dictionaryName').innerHTML = dictionaryName;
|
||||
const name = document.getElementById('dictionaryName');
|
||||
name.innerHTML = dictionaryName;
|
||||
const isPublic = hasToken() && window.currentDictionary.settings.isPublic;
|
||||
const shareLinkElement = document.getElementById('dictionaryShare');
|
||||
|
||||
if (isPublic && !shareLinkElement) {
|
||||
const shareLink = document.createElement('a');
|
||||
shareLink.id = 'dictionaryShare';
|
||||
shareLink.classList.add('button');
|
||||
shareLink.style.float = 'right';
|
||||
shareLink.href = 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;
|
||||
shareLink.target = '_blank';
|
||||
shareLink.title = 'Public Link to Dictionary';
|
||||
shareLink.innerHTML = '➦';
|
||||
name.parentElement.insertBefore(shareLink, name);
|
||||
} else if (!isPublic && shareLinkElement) {
|
||||
shareLinkElement.parentElement.removeChild(shareLinkElement);
|
||||
}
|
||||
}
|
||||
|
||||
export function renderDescription() {
|
||||
|
@ -179,10 +197,10 @@ export function renderWords() {
|
|||
<h4 class="word">${word.name}${homonymnNumber > 0 ? ' <sub>' + homonymnNumber.toString() + '</sub>' : ''}</h4>
|
||||
<span class="pronunciation">${word.pronunciation}</span>
|
||||
<span class="part-of-speech">${word.partOfSpeech}</span>
|
||||
${isPublic ? `<a class="small button share-link" href="${shareLink}" target="_blank" title="Public Link to Word">➦</a>` : ''}
|
||||
<span class="small button word-option-button">Options</span>
|
||||
<div class="word-option-list" style="display:none;">
|
||||
<div class="word-option" id="edit_${word.wordId}">Edit</div>
|
||||
${isPublic ? `<a class="word-option" href="${shareLink}" target="_blank">Share</a>` : ''}
|
||||
<div class="word-option" id="delete_${word.wordId}">Delete</div>
|
||||
</div>
|
||||
</header>
|
||||
|
@ -278,6 +296,12 @@ export function renderEditForm(wordId = false) {
|
|||
}
|
||||
}
|
||||
|
||||
export function renderIPAHelp() {
|
||||
import('./KeyboardFire/phondue/usage.html').then(html => {
|
||||
renderInfoModal(html);
|
||||
});
|
||||
}
|
||||
|
||||
export function renderIPATable(ipaTableButton) {
|
||||
ipaTableButton = typeof ipaTableButton.target === 'undefined' || ipaTableButton.target === '' ? ipaTableButton : ipaTableButton.target;
|
||||
const label = ipaTableButton.parentElement.innerText.replace(/(Field Help|IPA Chart)/g, '').trim();
|
||||
|
|
|
@ -8,6 +8,7 @@ import { enableHotKeys, disableHotKeys } from "./hotkeys";
|
|||
export function loadSettings() {
|
||||
const storedSettings = window.localStorage.getItem(SETTINGS_KEY);
|
||||
window.settings = storedSettings ? JSON.parse(storedSettings) : cloneObject(DEFAULT_SETTINGS);
|
||||
updateTheme();
|
||||
toggleIPAPronunciationFields();
|
||||
}
|
||||
|
||||
|
@ -16,11 +17,17 @@ export function saveSettings() {
|
|||
addMessage('Settings Saved!');
|
||||
}
|
||||
|
||||
export function updateTheme() {
|
||||
const { theme } = window.settings;
|
||||
document.body.id = theme + 'Theme';
|
||||
}
|
||||
|
||||
export function openSettingsModal() {
|
||||
const { useIPAPronunciationField, useHotkeys } = window.settings;
|
||||
const { useIPAPronunciationField, useHotkeys, theme } = window.settings;
|
||||
|
||||
document.getElementById('settingsUseIPA').checked = useIPAPronunciationField;
|
||||
document.getElementById('settingsUseHotkeys').checked = useHotkeys;
|
||||
document.getElementById('settingsTheme').value = theme;
|
||||
|
||||
document.getElementById('settingsModal').style.display = '';
|
||||
}
|
||||
|
@ -28,6 +35,7 @@ export function openSettingsModal() {
|
|||
export function saveSettingsModal() {
|
||||
window.settings.useIPAPronunciationField = document.getElementById('settingsUseIPA').checked;
|
||||
window.settings.useHotkeys = document.getElementById('settingsUseHotkeys').checked;
|
||||
window.settings.theme = document.getElementById('settingsTheme').value;
|
||||
|
||||
if (hasToken()) {
|
||||
import('./account/index.js').then(account => {
|
||||
|
@ -49,6 +57,7 @@ export function saveSettingsModal() {
|
|||
}
|
||||
|
||||
saveSettings();
|
||||
updateTheme();
|
||||
toggleHotkeysEnabled();
|
||||
toggleIPAPronunciationFields();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {showSection, hideDetailsPanel} from './displayToggles';
|
||||
import { renderWords, renderEditForm, renderMaximizedTextbox, renderInfoModal, renderIPATable } from './render';
|
||||
import { renderWords, renderEditForm, renderMaximizedTextbox, renderInfoModal, renderIPATable, renderIPAHelp } from './render';
|
||||
import { confirmEditWord, cancelEditWord, confirmDeleteWord, submitWordForm } from './wordManagement';
|
||||
import { openEditModal, saveEditModal, saveAndCloseEditModal, exportDictionary, exportWords, importDictionary, importWords, confirmDeleteDictionary } from './dictionaryManagement';
|
||||
import { goToNextPage, goToPreviousPage, goToPage } from './pagination';
|
||||
|
@ -287,11 +287,6 @@ export function setupIPAButtons() {
|
|||
button.addEventListener('click', renderIPATable);
|
||||
});
|
||||
|
||||
const renderIPAHelp = () => {
|
||||
import('./KeyboardFire/phondue/usage.html').then(html => {
|
||||
renderInfoModal(html);
|
||||
});
|
||||
}
|
||||
Array.from(ipaFieldHelpButtons).forEach(button => {
|
||||
button.removeEventListener('click', renderIPAHelp);
|
||||
button.addEventListener('click', renderIPAHelp);
|
||||
|
|
|
@ -4,6 +4,7 @@ import { getWordsStats, wordExists } from '../utilities';
|
|||
import { getMatchingSearchWords, highlightSearchTerm, getSearchFilters, getSearchTerm } from '../search';
|
||||
import { showSection } from '../displayToggles';
|
||||
import { setupSearchFilters, setupInfoModal } from './setupListeners';
|
||||
import { parseReferences } from '../wordManagement';
|
||||
|
||||
export function renderAll() {
|
||||
renderDictionaryDetails();
|
||||
|
@ -25,6 +26,9 @@ export function renderDictionaryDetails() {
|
|||
export function renderName() {
|
||||
const dictionaryName = removeTags(window.currentDictionary.name) + ' ' + removeTags(window.currentDictionary.specification);
|
||||
document.getElementById('dictionaryName').innerHTML = dictionaryName;
|
||||
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;
|
||||
}
|
||||
|
||||
export function renderDescription() {
|
||||
|
@ -134,18 +138,8 @@ export function renderWords() {
|
|||
}
|
||||
|
||||
words.forEach(originalWord => {
|
||||
let detailsMarkdown = removeTags(originalWord.details);
|
||||
const references = detailsMarkdown.match(/\{\{.+?\}\}/g);
|
||||
if (references && Array.isArray(references)) {
|
||||
new Set(references).forEach(reference => {
|
||||
const wordToFind = reference.replace(/\{\{|\}\}/g, '');
|
||||
const existingWordId = wordExists(wordToFind, true);
|
||||
if (existingWordId !== false) {
|
||||
const wordMarkdownLink = `[${wordToFind}](#${existingWordId})`;
|
||||
detailsMarkdown = detailsMarkdown.replace(new RegExp(reference, 'g'), wordMarkdownLink);
|
||||
}
|
||||
});
|
||||
}
|
||||
let detailsMarkdown = originalWord.details;
|
||||
detailsMarkdown = parseReferences(detailsMarkdown);
|
||||
const word = highlightSearchTerm({
|
||||
name: removeTags(originalWord.name),
|
||||
pronunciation: removeTags(originalWord.pronunciation),
|
||||
|
@ -154,11 +148,13 @@ export function renderWords() {
|
|||
details: detailsMarkdown,
|
||||
wordId: originalWord.wordId,
|
||||
});
|
||||
const shareLink = window.location.pathname + (window.location.pathname.match(new RegExp(word.wordId + '$')) ? '' : '/' + word.wordId);
|
||||
wordsHTML += `<article class="entry" id="${word.wordId}">
|
||||
<header>
|
||||
<h4 class="word">${word.name}</h4>
|
||||
<span class="pronunciation">${word.pronunciation}</span>
|
||||
<span class="part-of-speech">${word.partOfSpeech}</span>
|
||||
<a href="${shareLink}" target="_blank" class="small button word-option-button" title="Link to Word">➦</a>
|
||||
</header>
|
||||
<dl>
|
||||
<dt class="definition">${word.definition}</dt>
|
||||
|
|
|
@ -46,43 +46,46 @@ export function sortWords(render) {
|
|||
}
|
||||
}
|
||||
|
||||
export function parseReferences(detailsMarkdown, references) {
|
||||
new Set(references).forEach(reference => {
|
||||
let wordToFind = reference.replace(/\{\{|\}\}/g, '');
|
||||
let homonymn = 0;
|
||||
|
||||
if (wordToFind.includes(':')) {
|
||||
const separator = wordToFind.indexOf(':');
|
||||
homonymn = wordToFind.substr(separator + 1);
|
||||
wordToFind = wordToFind.substring(0, separator);
|
||||
if (homonymn && homonymn.trim()
|
||||
&& !isNaN(parseInt(homonymn.trim())) && parseInt(homonymn.trim()) > 0) {
|
||||
homonymn = parseInt(homonymn.trim());
|
||||
} else {
|
||||
homonymn = false;
|
||||
export function parseReferences(detailsMarkdown) {
|
||||
const references = detailsMarkdown.match(/\{\{.+?\}\}/g);
|
||||
if (references && Array.isArray(references)) {
|
||||
new Set(references).forEach(reference => {
|
||||
let wordToFind = reference.replace(/\{\{|\}\}/g, '');
|
||||
let homonymn = 0;
|
||||
|
||||
if (wordToFind.includes(':')) {
|
||||
const separator = wordToFind.indexOf(':');
|
||||
homonymn = wordToFind.substr(separator + 1);
|
||||
wordToFind = wordToFind.substring(0, separator);
|
||||
if (homonymn && homonymn.trim()
|
||||
&& !isNaN(parseInt(homonymn.trim())) && parseInt(homonymn.trim()) > 0) {
|
||||
homonymn = parseInt(homonymn.trim());
|
||||
} else {
|
||||
homonymn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let existingWordId = false;
|
||||
const homonymnIndexes = getHomonymnIndexes({ name: wordToFind, wordId: -1 });
|
||||
let existingWordId = false;
|
||||
const homonymnIndexes = getHomonymnIndexes({ name: wordToFind, wordId: -1 });
|
||||
|
||||
if (homonymn !== false && homonymn > 0) {
|
||||
if (typeof homonymnIndexes[homonymn - 1] !== 'undefined') {
|
||||
existingWordId = window.currentDictionary.words[homonymnIndexes[homonymn - 1]].wordId;
|
||||
if (homonymn !== false && homonymn > 0) {
|
||||
if (typeof homonymnIndexes[homonymn - 1] !== 'undefined') {
|
||||
existingWordId = window.currentDictionary.words[homonymnIndexes[homonymn - 1]].wordId;
|
||||
}
|
||||
} else if (homonymn !== false) {
|
||||
existingWordId = wordExists(wordToFind, true);
|
||||
}
|
||||
} else if (homonymn !== false) {
|
||||
existingWordId = wordExists(wordToFind, true);
|
||||
}
|
||||
|
||||
if (existingWordId !== false) {
|
||||
if (homonymn < 1 && homonymnIndexes.length > 0) {
|
||||
homonymn = 1;
|
||||
if (existingWordId !== false) {
|
||||
if (homonymn < 1 && homonymnIndexes.length > 0) {
|
||||
homonymn = 1;
|
||||
}
|
||||
const homonymnSubHTML = homonymn > 0 ? '<sub>' + homonymn.toString() + '</sub>' : '';
|
||||
const wordMarkdownLink = `[${wordToFind}${homonymnSubHTML}](#${existingWordId})`;
|
||||
detailsMarkdown = detailsMarkdown.replace(new RegExp(reference, 'g'), wordMarkdownLink);
|
||||
}
|
||||
const homonymnSubHTML = homonymn > 0 ? '<sub>' + homonymn.toString() + '</sub>' : '';
|
||||
const wordMarkdownLink = `[${wordToFind}${homonymnSubHTML}](#${existingWordId})`;
|
||||
detailsMarkdown = detailsMarkdown.replace(new RegExp(reference, 'g'), wordMarkdownLink);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return detailsMarkdown;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
@import 'scss/mobile/structure';
|
||||
@import 'scss/mobile/elements';
|
||||
|
||||
@import 'scss/themes/default';
|
||||
|
||||
html, body {
|
||||
font-family: $font;
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
RewriteEngine On # Turn on the rewriting engine
|
||||
|
||||
RewriteRule ^view/([0-9]+)/([0-9]+)/?$ api/router.php?view=publicview&dict=$1&word=$2 [NC,L] # Handle word ids.
|
||||
RewriteRule ^view/([0-9]+)/([0-9]+)/?$ api/router.php?view=word&dict=$1&word=$2 [NC,L] # Handle word ids.
|
||||
|
||||
RewriteRule ^([0-9]+)/([0-9]+)/?$ api/router.php?view=publicview&dict=$1&word=$2 [NC,L] # Handle word ids.
|
||||
RewriteRule ^([0-9]+)/([0-9]+)/?$ api/router.php?view=word&dict=$1&word=$2 [NC,L] # Handle word ids.
|
||||
|
||||
RewriteRule ^view/([0-9]+)/?$ api/router.php?view=publicview&dict=$1 [NC,L] # Handle dictionary ids.
|
||||
RewriteRule ^view/([0-9]+)/?$ api/router.php?view=dictionary&dict=$1 [NC,L] # Handle dictionary ids.
|
||||
|
||||
RewriteRule ^([0-9]+)/?$ api/router.php?view=publicview&dict=$1 [NC,L] # Handle dictionary ids.
|
||||
RewriteRule ^([0-9]+)/?$ api/router.php?view=dictionary&dict=$1 [NC,L] # Handle dictionary ids.
|
||||
|
||||
#RewriteRule ^issues/?$ https://github.com/Alamantus/Lexiconga/issues [R=301,L] # Shorten issues url.
|
||||
|
||||
|
|
|
@ -143,13 +143,13 @@ VALUES ($new_id, ?, ?, ?, ?)";
|
|||
$query = "SELECT words.* FROM words JOIN dictionaries ON id = dictionary WHERE dictionary=? AND is_public=1";
|
||||
$results = $this->db->query($query, array($dictionary))->fetchAll();
|
||||
if ($results) {
|
||||
return array_map(function ($row) {
|
||||
return array_map(function ($row) use ($dictionary) {
|
||||
return array(
|
||||
'name' => $row['name'],
|
||||
'pronunciation' => $row['pronunciation'],
|
||||
'partOfSpeech' => $row['part_of_speech'],
|
||||
'definition' => $row['definition'],
|
||||
'details' => $row['details'],
|
||||
'details' => $this->parseReferences($row['details'], $dictionary),
|
||||
'lastUpdated' => is_null($row['last_updated']) ? intval($row['created_on']) : intval($row['last_updated']),
|
||||
'createdOn' => intval($row['created_on']),
|
||||
'wordId' => intval($row['word_id']),
|
||||
|
@ -160,6 +160,87 @@ VALUES ($new_id, ?, ?, ?, ?)";
|
|||
return array();
|
||||
}
|
||||
|
||||
public function getSpecificPublicDictionaryWord ($dictionary, $word) {
|
||||
if (is_numeric($dictionary) && is_numeric($word)) {
|
||||
$query = "SELECT words.* FROM words JOIN dictionaries ON id = dictionary WHERE dictionary=? AND word_id=? AND is_public=1";
|
||||
$result = $this->db->query($query, array($dictionary, $word))->fetch();
|
||||
if ($result) {
|
||||
return array(
|
||||
'name' => $result['name'],
|
||||
'pronunciation' => $result['pronunciation'],
|
||||
'partOfSpeech' => $result['part_of_speech'],
|
||||
'definition' => $result['definition'],
|
||||
'details' => $this->parseReferences($result['details'], $dictionary),
|
||||
'lastUpdated' => is_null($result['last_updated']) ? intval($result['created_on']) : intval($result['last_updated']),
|
||||
'createdOn' => intval($result['created_on']),
|
||||
'wordId' => intval($result['word_id']),
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function parseReferences($details, $dictionary_id) {
|
||||
$details = strip_tags($details);
|
||||
if (preg_match_all('/\{\{.+?\}\}/', $details, $references) !== false) {
|
||||
$references = array_unique($references[0]);
|
||||
foreach($references as $reference) {
|
||||
$word_to_find = preg_replace('/\{\{|\}\}/', '', $reference);
|
||||
$homonymn = 0;
|
||||
|
||||
if (strpos($word_to_find, ':') !== false) {
|
||||
$separator = strpos($word_to_find, ':');
|
||||
$homonymn = substr($word_to_find, $separator + 1);
|
||||
$word_to_find = substr($word_to_find, 0, $separator);
|
||||
if ($homonymn && trim($homonymn) && intval(trim($homonymn)) > 0) {
|
||||
$homonymn = intval(trim($homonymn));
|
||||
} else {
|
||||
$homonymn = false;
|
||||
}
|
||||
}
|
||||
|
||||
$target_id = false;
|
||||
$reference_ids = $this->getWordIdsWithName($dictionary_id, $word_to_find);
|
||||
|
||||
if (count($reference_ids) > 0) {
|
||||
if ($homonymn !== false && $homonymn > 0) {
|
||||
if (isset($reference_ids[$homonymn - 1])) {
|
||||
$target_id = $reference_ids[$homonymn - 1];
|
||||
}
|
||||
} else if ($homonymn !== false) {
|
||||
$target_id = $reference_ids[0];
|
||||
}
|
||||
|
||||
if ($target_id !== false) {
|
||||
if ($homonymn < 1) {
|
||||
$homonymn = 1;
|
||||
}
|
||||
$homonymn_sub_html = $homonymn > 0 ? '<sub>' . $homonymn . '</sub>' : '';
|
||||
$site_root = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], $dictionary_id));
|
||||
$markdown_link = '<a href="' . $site_root . $dictionary_id . '/' . $target_id .'" target="_blank" title="Link to Reference">'
|
||||
. $word_to_find . $homonymn_sub_html . '</a>';
|
||||
$details = str_replace($reference, $markdown_link, $details);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $details;
|
||||
}
|
||||
|
||||
private function getWordIdsWithName($dictionary, $word_name) {
|
||||
if (is_numeric($dictionary)) {
|
||||
$query = "SELECT word_id FROM words WHERE dictionary=? AND name=?";
|
||||
$results = $this->db->query($query, array($dictionary, $word_name))->fetchAll();
|
||||
if ($results) {
|
||||
return array_map(function ($row) {
|
||||
return intval($row['word_id']);
|
||||
}, $results);
|
||||
}
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getDetails ($user, $dictionary) {
|
||||
$query = "SELECT * FROM dictionaries JOIN dictionary_linguistics ON dictionary = id WHERE user=$user AND id=$dictionary";
|
||||
$result = $this->db->query($query)->fetch();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
$view = isset($_GET['view']) ? $_GET['view'] : false;
|
||||
|
||||
switch ($view) {
|
||||
case 'publicview': {
|
||||
case 'dictionary': {
|
||||
$html = file_get_contents('../view.html');
|
||||
$dict = isset($_GET['dict']) ? $_GET['dict'] : false;
|
||||
if ($dict !== false) {
|
||||
|
@ -26,4 +26,43 @@ switch ($view) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 'word': {
|
||||
$html = file_get_contents('../view.html');
|
||||
$dict = isset($_GET['dict']) ? $_GET['dict'] : false;
|
||||
$word = isset($_GET['word']) ? $_GET['word'] : false;
|
||||
if ($dict !== false && $word !== false) {
|
||||
require_once('./Dictionary.php');
|
||||
$dictionary = new Dictionary();
|
||||
$dictionary_data = $dictionary->getPublicDictionaryDetails($dict);
|
||||
if ($dictionary_data !== false) {
|
||||
$dictionary_name = $dictionary_data['name'] . ' ' . $dictionary_data['specification'];
|
||||
$word_data = $dictionary->getSpecificPublicDictionaryWord($dict, $word);
|
||||
if ($word_data === false) {
|
||||
$word_data = array(
|
||||
'name' => 'Error: Word Not Found',
|
||||
'pronunciation' => '',
|
||||
'partOfSpeech' => '',
|
||||
'definition' => 'No word with the id ' . $word . ' was found in the ' . $dictionary_name,
|
||||
'details' => '',
|
||||
'lastUpdated' => null,
|
||||
'createdOn' => null,
|
||||
'wordId' => null,
|
||||
);
|
||||
}
|
||||
$dictionary_data['words'] = array($word_data);
|
||||
$html = str_replace('{{dict}}', $dict, $html);
|
||||
$html = str_replace('{{dict_name}}', $word_data['name'] . ' in the ' . $dictionary_name, $html);
|
||||
$html = str_replace('{{public_name}}', $dictionary_data['createdBy'], $html);
|
||||
$dictionary_json = json_encode($dictionary_data);
|
||||
$html = str_replace('{{dict_json}}', addslashes($dictionary_json), $html);
|
||||
} else {
|
||||
$html = str_replace('{{dict}}', 'error', $html);
|
||||
$html = str_replace('{{dict_name}}', 'Error: Dictionary Not Found', $html);
|
||||
$html = str_replace('{{public_name}}', 'Error', $html);
|
||||
$html = str_replace('{{dict_json}}', '{"name": "Error:", "specification": "Dictionary Not Found", "words": []}', $html);
|
||||
}
|
||||
echo $html;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -13,4 +13,10 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.share-link {
|
||||
margin-left: $general-padding !important;
|
||||
line-height: 16px !important;
|
||||
padding: 1px 3px 3px !important;
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
header {
|
||||
display: block;
|
||||
padding: 5px $general-padding;
|
||||
border-bottom: 1px solid $mid;
|
||||
margin: 0 0 5px;
|
||||
|
||||
&#top {
|
||||
|
@ -14,7 +13,7 @@ main {
|
|||
width: 90%;
|
||||
max-width: 1000px;
|
||||
min-height: 400px;
|
||||
margin: 0 auto;
|
||||
margin: 0 auto ($header-height * 1.25);
|
||||
|
||||
#sideColumn,
|
||||
#mainColumn {
|
||||
|
@ -29,13 +28,12 @@ main {
|
|||
|
||||
#mainColumn {
|
||||
width: 64%;
|
||||
margin: 0;
|
||||
margin: $general-padding 0 0;
|
||||
}
|
||||
|
||||
article {
|
||||
width: 95%;
|
||||
margin: 10px auto;
|
||||
border: $border;
|
||||
|
||||
dl {
|
||||
padding: 0 $general-padding;
|
||||
|
@ -46,6 +44,5 @@ main {
|
|||
footer {
|
||||
display: block;
|
||||
padding: $general-padding;
|
||||
border-top: 1px solid $mid;
|
||||
margin: 5px 0 0;
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
p, span {
|
||||
&.red {
|
||||
color: $red;
|
||||
}
|
||||
a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
p, span {
|
||||
&.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -34,24 +34,42 @@ label {
|
|||
}
|
||||
|
||||
.label-button {
|
||||
@extend .button;
|
||||
|
||||
display: inline-block;
|
||||
padding: 3px 9px;
|
||||
border-radius: 3px;
|
||||
line-height: 30px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
font-size: 80%;
|
||||
font-weight: normal;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
line-height: 80% !important;
|
||||
padding: 3px 3px 5px;
|
||||
|
||||
&.small {
|
||||
font-size: 80%;
|
||||
line-height: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
.label-help-button {
|
||||
@extend .button;
|
||||
|
||||
display: inline-block;
|
||||
padding: 3px 9px;
|
||||
border-radius: 3px;
|
||||
line-height: 30px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
font-size: 70%;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
line-height: 70% !important;
|
||||
padding: 2px 2px 4px;
|
||||
|
||||
&.small {
|
||||
font-size: 80%;
|
||||
line-height: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,38 +80,46 @@ ul {
|
|||
.tag {
|
||||
display: inline-block;
|
||||
padding: 3px 9px;
|
||||
border: $border;
|
||||
border-radius: 3px;
|
||||
background-color: $light;
|
||||
line-height: 30px;
|
||||
|
||||
&.small {
|
||||
font-size: 80%;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
&.red {
|
||||
background-color: $red;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
span .tag {
|
||||
@extend .tag;
|
||||
|
||||
border-radius: 3px 0 0 3px;
|
||||
|
||||
display: inline-block;
|
||||
padding: 3px 9px;
|
||||
border-radius: 3px;
|
||||
line-height: 30px;
|
||||
|
||||
&.small {
|
||||
font-size: 80%;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
&+.tag {
|
||||
border-left: none;
|
||||
border-radius: 0 3px 3px 0;
|
||||
background-color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
@extend .tag;
|
||||
display: inline-block;
|
||||
padding: 3px 9px;
|
||||
border-radius: 3px;
|
||||
line-height: 30px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&.small {
|
||||
font-size: 80%;
|
||||
line-height: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
|
@ -109,7 +135,6 @@ span .tag {
|
|||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #000000;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
|
@ -122,8 +147,6 @@ span .tag {
|
|||
max-width: 100%;
|
||||
height: 600px;
|
||||
max-height: 100%;
|
||||
background-color: $white;
|
||||
border: $border;
|
||||
border-radius: 5px;
|
||||
|
||||
.close-button {
|
||||
|
@ -139,25 +162,13 @@ span .tag {
|
|||
}
|
||||
|
||||
.tabs {
|
||||
ul {
|
||||
border-bottom: $border;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
margin: 0 2px -1px;
|
||||
padding: 10px $general-padding;
|
||||
border-top: $border;
|
||||
border-left: $border;
|
||||
border-right: $border;
|
||||
border-radius: 5px 5px 0 0;
|
||||
background-color: $mid;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
background-color: $white;
|
||||
border-bottom: 1px solid $white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
left: unset;
|
||||
bottom: unset;
|
||||
right: unset;
|
||||
background-color: $white;
|
||||
padding: ($general-padding / 2) $general-padding ($general-padding * 0.25);
|
||||
font-size: 90%;
|
||||
|
||||
|
@ -100,16 +99,13 @@
|
|||
|
||||
#wordForm {
|
||||
position: fixed;
|
||||
top: auto;
|
||||
top: $header-height + $general-padding;
|
||||
width: 31%;
|
||||
max-width: 320px;
|
||||
padding: 10px;
|
||||
background-color: $light;
|
||||
border: $border;
|
||||
border-radius: 5px;
|
||||
max-height: 80%;
|
||||
overflow-y: auto;
|
||||
box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
}
|
||||
|
||||
.edit-form {
|
||||
|
@ -117,11 +113,12 @@
|
|||
max-width: 500px;
|
||||
}
|
||||
|
||||
#detailsSection {
|
||||
padding: $general-padding;
|
||||
background-color: $white;
|
||||
border: $border;
|
||||
#mainColumn {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#detailsSection {
|
||||
padding: $general-padding $general-padding 0;
|
||||
|
||||
#dictionaryName {
|
||||
margin-top: 0;
|
||||
|
@ -135,8 +132,6 @@
|
|||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 10px $general-padding;
|
||||
border: $border;
|
||||
background-color: $light;
|
||||
cursor: pointer;
|
||||
|
||||
&:first-child {
|
||||
|
@ -148,15 +143,10 @@
|
|||
&:not(:first-child) {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #bababa;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#detailsPanel {
|
||||
background-color: $white;
|
||||
padding: $general-padding;
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
|
@ -170,8 +160,6 @@
|
|||
|
||||
|
||||
.entry {
|
||||
background-color: $light;
|
||||
|
||||
.word {
|
||||
display: inline-block;
|
||||
margin: 3px 0;
|
||||
|
@ -202,15 +190,12 @@
|
|||
position: absolute;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
background-color: $white;
|
||||
border: $border;
|
||||
border-radius: 5px;
|
||||
|
||||
.word-option {
|
||||
padding: 10px 25px;;
|
||||
|
||||
&:hover {
|
||||
background-color: $light;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
@ -339,13 +324,12 @@ $nav-font-height: 16px;
|
|||
bottom: $general-padding;
|
||||
right: $general-padding;
|
||||
max-width: 300px;
|
||||
z-index: 10;
|
||||
|
||||
.message {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: $general-padding ($general-padding * 2) $general-padding $general-padding;
|
||||
background-color: $light;
|
||||
border: $border;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 5px;
|
||||
|
||||
|
@ -353,10 +337,6 @@ $nav-font-height: 16px;
|
|||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.error {
|
||||
background-color: lighten($red, 0.75);
|
||||
}
|
||||
|
||||
.close-button {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
|
@ -372,7 +352,6 @@ $nav-font-height: 16px;
|
|||
right: -2px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #455455;
|
||||
opacity: 0.5;
|
||||
transform-origin: center left;
|
||||
transform: scaleX(0);
|
||||
|
@ -391,10 +370,19 @@ $nav-font-height: 16px;
|
|||
}
|
||||
|
||||
#bottom {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 5;
|
||||
text-align: center;
|
||||
padding: $general-padding / 2;
|
||||
|
||||
a {
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.separator {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@ $font: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubunt
|
|||
|
||||
$header-height: 60px;
|
||||
|
||||
$dark: #bababa;
|
||||
$mid: #dedede;
|
||||
$light: #efefef;
|
||||
$white: #ffffff;
|
||||
// $dark: #bababa;
|
||||
// $mid: #dedede;
|
||||
// $light: #efefef;
|
||||
// $white: #ffffff;
|
||||
|
||||
$red: #d42932;
|
||||
// $red: #d42932;
|
||||
|
||||
$border: 1px solid $dark;
|
||||
// $border: 1px solid $dark;
|
||||
$general-padding: 20px;
|
|
@ -12,6 +12,8 @@ header {
|
|||
}
|
||||
|
||||
main {
|
||||
margin-bottom: $general-padding;
|
||||
|
||||
#sideColumn {
|
||||
display: block;
|
||||
width: 0;
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
@media (max-width: 750px) {
|
||||
|
||||
.tag {
|
||||
padding: 2px 6px;
|
||||
font-size: 90%;
|
||||
line-height: 120%;
|
||||
// .tag {
|
||||
// padding: 2px 6px;
|
||||
// font-size: 90%;
|
||||
// line-height: 120%;
|
||||
|
||||
&.small {
|
||||
font-size: 70%;
|
||||
line-height: 100%;
|
||||
}
|
||||
}
|
||||
// &.small {
|
||||
// font-size: 70%;
|
||||
// line-height: 100%;
|
||||
// }
|
||||
// }
|
||||
|
||||
.button {
|
||||
@extend .tag;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
// .button {
|
||||
// @extend .tag;
|
||||
// cursor: pointer;
|
||||
// user-select: none;
|
||||
// }
|
||||
|
||||
.tabs {
|
||||
li {
|
||||
|
|
|
@ -34,10 +34,7 @@
|
|||
width: 32px;
|
||||
height: 32px;
|
||||
display: block;
|
||||
background-color: #00de00;
|
||||
border: $border;
|
||||
border-radius: 0 3px 3px 0;
|
||||
color: $white;
|
||||
font-size: 30px;
|
||||
line-height: 24px;
|
||||
font-weight: bold;
|
||||
|
@ -88,4 +85,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
#bottom {
|
||||
position: relative;
|
||||
bottom: unset;
|
||||
|
||||
.separator {
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
#defaultTheme {
|
||||
$dark: #bababa;
|
||||
$mid: #dedede;
|
||||
$light: #efefef;
|
||||
$white: #ffffff;
|
||||
$red: #b42032;
|
||||
|
||||
$header-color: #eacc9d;
|
||||
$background-color: #e6cfaa;
|
||||
$footer-color: #cb6318;
|
||||
$link-color: #a01000;
|
||||
$button-color: #dcb078;
|
||||
$message-color: #c0c088;
|
||||
$word-form-color: #ba5536;
|
||||
$dictionary-color: #bd7251;
|
||||
$entry-color: #d7ad7d;
|
||||
$input-color: #efdfc0;
|
||||
$details-color: #f2d5b2;
|
||||
$modal-color: #f2d5b2;
|
||||
|
||||
$border: 1px solid $dark;
|
||||
|
||||
background-color: $background-color;
|
||||
|
||||
a {
|
||||
color: $link-color;
|
||||
}
|
||||
|
||||
p, span {
|
||||
&.red {
|
||||
color: $red;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
.label-button {
|
||||
border: 1px solid darken($button-color, 2);
|
||||
background-color: $button-color;
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.label-help-button {
|
||||
border: 1px solid darken($button-color, 2);
|
||||
background-color: $button-color;
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
input, textarea, select, option {
|
||||
background-color: $input-color;
|
||||
}
|
||||
|
||||
.tag {
|
||||
border: $border;
|
||||
background-color: $button-color;
|
||||
|
||||
&.red {
|
||||
background-color: $red;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
span .tag {
|
||||
border: $border;
|
||||
background-color: $button-color;
|
||||
&+.tag {
|
||||
background-color: lighten($button-color, 25);
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
border: 1px solid darken($button-color, 2);
|
||||
background-color: $button-color;
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
|
||||
&.red {
|
||||
background-color: $red;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
.modal-background {
|
||||
background-color: #000000;
|
||||
}
|
||||
.modal-content {
|
||||
background-color: $modal-color;
|
||||
border: 1px solid darken($modal-color, 10);
|
||||
}
|
||||
}
|
||||
|
||||
.tabs {
|
||||
ul {
|
||||
border-bottom: $border;
|
||||
}
|
||||
li {
|
||||
border-top: $border;
|
||||
border-left: $border;
|
||||
border-right: $border;
|
||||
background-color: $button-color;
|
||||
|
||||
&.active {
|
||||
background-color: $modal-color;
|
||||
border-bottom: 1px solid $modal-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header {
|
||||
border-bottom: 1px solid $mid;
|
||||
}
|
||||
|
||||
main {
|
||||
article {
|
||||
border: $border;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
border-top: 1px solid $mid;
|
||||
}
|
||||
|
||||
#top {
|
||||
background-color: $header-color;
|
||||
border-bottom: 1px solid darken($header-color, 2);
|
||||
box-shadow: 0px 4px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
|
||||
#title {
|
||||
display: inline-block;
|
||||
margin: 3px $general-padding 3px 0;
|
||||
}
|
||||
|
||||
#openSearchModal {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#searchModal {
|
||||
.modal-content {
|
||||
section+footer {
|
||||
background-color: $modal-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#wordForm {
|
||||
background-color: $word-form-color;
|
||||
border: 1px solid darken($word-form-color, 2);
|
||||
box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
}
|
||||
|
||||
#mainColumn {
|
||||
background-color: $dictionary-color;
|
||||
border: 1px solid darken($dictionary-color, 2);
|
||||
box-shadow: 4px 4px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
}
|
||||
|
||||
#detailsSection {
|
||||
nav ul {
|
||||
li {
|
||||
border: 1px solid darken($button-color, 20);
|
||||
background-color: $button-color;
|
||||
|
||||
&.active {
|
||||
background-color: lighten($button-color, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#detailsPanel {
|
||||
background-color: $details-color;
|
||||
}
|
||||
}
|
||||
|
||||
.entry {
|
||||
background-color: $entry-color;
|
||||
border: 1px solid darken($entry-color, 20);
|
||||
|
||||
header {
|
||||
border-bottom: 1px solid darken($entry-color, 20);
|
||||
|
||||
.word-option-button {
|
||||
background-color: darken($entry-color, 10);
|
||||
border: 1px solid darken($entry-color, 20);
|
||||
}
|
||||
|
||||
.word-option-list {
|
||||
background-color: darken($entry-color, 5);
|
||||
border: 1px solid darken($entry-color, 10);
|
||||
|
||||
.word-option {
|
||||
&:hover {
|
||||
background-color: lighten($entry-color, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edit-form {
|
||||
.button {
|
||||
background-color: darken($button-color, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#messagingSection {
|
||||
.message {
|
||||
background-color: $message-color;
|
||||
border: $border;
|
||||
|
||||
&.error {
|
||||
background-color: lighten($red, 0.75);
|
||||
}
|
||||
|
||||
.close-button {
|
||||
&:before {
|
||||
background-color: #455455;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#bottom {
|
||||
background-color: $footer-color;
|
||||
border-top: 1px solid darken($footer-color, 2);
|
||||
box-shadow: 0px -4px 5px 0px rgba(50, 50, 50, 0.75);
|
||||
|
||||
a {
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 750px) {
|
||||
#defaultTheme {
|
||||
$dark: #bababa;
|
||||
$mid: #dedede;
|
||||
$light: #efefef;
|
||||
$white: #ffffff;
|
||||
$red: #b42032;
|
||||
$border: 1px solid $dark;
|
||||
|
||||
#mobileWordFormShow {
|
||||
background-color: #00de00;
|
||||
border: $border;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -109,7 +109,9 @@
|
|||
|
||||
<section id="mainColumn">
|
||||
<section id="detailsSection">
|
||||
<h2 id="dictionaryName">Dictionary Name</h2>
|
||||
<a id="dictionaryShare" href="./" class="button" title="Link to Dictionary" style="float:right;">➦</a>
|
||||
<h2 id="dictionaryName">{{dict_name}}</h2>
|
||||
<h4>Created by {{public_name}}</h4>
|
||||
<nav>
|
||||
<ul>
|
||||
<li>Description</li><li>Details</li><li>Stats</li><!-- li id="editDictionaryButton">Edit</li -->
|
||||
|
|
Loading…
Reference in New Issue