Merge pull request 'Initial working draft' (#1) from dev into main
Reviewed-on: #1
This commit is contained in:
commit
45773d3b80
@ -1,10 +1,12 @@
|
|||||||
.d-l10n-translate-template {
|
.d-l10n-translate-template {
|
||||||
display: none;
|
color: gainsboro;
|
||||||
}
|
}
|
||||||
|
|
||||||
.d-l10n-translated {
|
.d-l10n-translated {
|
||||||
text-decoration: underline dotted;
|
text-decoration: underline dotted;
|
||||||
cursor: pointer;
|
}
|
||||||
|
|
||||||
|
.d-l10n-translated-reference {
|
||||||
}
|
}
|
||||||
|
|
||||||
.d-l10n-translated-entity-name {
|
.d-l10n-translated-entity-name {
|
||||||
@ -27,11 +29,11 @@
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.d-l10n-translated-original:before {
|
.d-l10n-translated-non-cjk:before {
|
||||||
content: ' '
|
content: ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
.d-l10n-translated-original:after {
|
.d-l10n-translated-non-cjk:after {
|
||||||
content: ' '
|
content: ' '
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,3 +49,31 @@
|
|||||||
.d-l10n-color {
|
.d-l10n-color {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.d-l10n-control-box {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row;
|
||||||
|
border: 1px solid gray;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d-l10n-control-box-item {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-flow: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d-l10n-control-box-item-label {
|
||||||
|
display: block;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d-l10n-control-box-vertical-divider {
|
||||||
|
border-left: 1px solid gray;
|
||||||
|
margin-left: 1rem;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d-l10n-translated-error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
@ -36,8 +36,39 @@ function isCjkContext(str) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupControls() {
|
||||||
|
const translationModeBox = document.getElementById('d-l10n-translation-mode')
|
||||||
|
const annotationModeBox = document.getElementById('d-l10n-annotation-mode')
|
||||||
|
|
||||||
|
if (translationModeBox == null) {
|
||||||
|
console.error('d-l10n-translation-mode not found')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (annotationModeBox == null) {
|
||||||
|
console.error('d-l10n-annotation-mode not found')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentPreferredTranslation = getPreferredTranslation()
|
||||||
|
translationModeBox.value = currentPreferredTranslation
|
||||||
|
|
||||||
|
const currentPreferredAnnotation = getPreferredAnnotation()
|
||||||
|
annotationModeBox.value = currentPreferredAnnotation
|
||||||
|
|
||||||
|
translationModeBox.addEventListener('change', (event) => {
|
||||||
|
changePreferredTranslation(event.target.value)
|
||||||
|
processTranslationBoxes()
|
||||||
|
})
|
||||||
|
|
||||||
|
annotationModeBox.addEventListener('change', (event) => {
|
||||||
|
changePreferredAnnotation(event.target.value)
|
||||||
|
processTranslationBoxes()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function processColorBoxes() {
|
function processColorBoxes() {
|
||||||
const allColorBoxes = document.querySelectorAll(".d-l10n-color");
|
const allColorBoxes = document.querySelectorAll(".d-l10n-color")
|
||||||
|
|
||||||
const knownColors = {}
|
const knownColors = {}
|
||||||
|
|
||||||
@ -46,22 +77,22 @@ function processColorBoxes() {
|
|||||||
const key = colorBox.innerHTML
|
const key = colorBox.innerHTML
|
||||||
const value = colorBox.getAttribute('data-color')
|
const value = colorBox.getAttribute('data-color')
|
||||||
if (value == null || value.length < 1) {
|
if (value == null || value.length < 1) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
knownColors[key] = value
|
knownColors[key] = value
|
||||||
});
|
})
|
||||||
|
|
||||||
// second pass: add a little box with the color
|
// second pass: add a little box with the color
|
||||||
allColorBoxes.forEach((colorBox) => {
|
allColorBoxes.forEach((colorBox) => {
|
||||||
const key = colorBox.innerHTML
|
const key = colorBox.innerHTML
|
||||||
const value = knownColors[key]
|
const value = knownColors[key]
|
||||||
if (value == null || value.length < 1) {
|
if (value == null || value.length < 1) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
colorBox.innerHTML = `<span class="d-l10n-color-box" style="background-color: ${value}" title="${value}"></span> ${key}`
|
colorBox.innerHTML = `<span class="d-l10n-color-box" style="background-color: ${value}" title="${value}"></span> ${key}`
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPreferredTranslation() {
|
function getPreferredTranslation() {
|
||||||
@ -69,7 +100,7 @@ function getPreferredTranslation() {
|
|||||||
return localStorage.getItem("d-l10n-preferred-translation") || 'writer'
|
return localStorage.getItem("d-l10n-preferred-translation") || 'writer'
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'writer';
|
return 'writer'
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePreferredTranslation(mode) {
|
function changePreferredTranslation(mode) {
|
||||||
@ -83,8 +114,48 @@ function changePreferredTranslation(mode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPreferredAnnotation() {
|
||||||
|
if (localStorage) {
|
||||||
|
return localStorage.getItem("d-l10n-preferred-annotation") || 'hide'
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'hide'
|
||||||
|
}
|
||||||
|
|
||||||
|
function changePreferredAnnotation(mode) {
|
||||||
|
// can be 'none', 'parenthesis', 'ruby'
|
||||||
|
if (mode !== 'hide' && mode !== 'parenthesis' && mode !== 'ruby') {
|
||||||
|
mode = 'hide'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localStorage) {
|
||||||
|
localStorage.setItem("d-l10n-preferred-annotation", mode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processInlineAnnotation(box, processedString) {
|
||||||
|
const original = box.getAttribute('data-original')
|
||||||
|
|
||||||
|
return `${processedString} <span class="d-l10n-translated-inline-annotation">(${original})</span> `
|
||||||
|
}
|
||||||
|
|
||||||
|
function processRubyAnnotation(box, processedString) {
|
||||||
|
const original = box.getAttribute('data-original')
|
||||||
|
|
||||||
|
return `<ruby>${processedString}<rp>(</rp><rt>${original}</rt><rp>)</rp></ruby>`
|
||||||
|
}
|
||||||
|
|
||||||
function processTranslationBoxes() {
|
function processTranslationBoxes() {
|
||||||
const boxes = document.querySelectorAll(".d-l10n-translate-template");
|
const boxes = document.querySelectorAll(".d-l10n-translate-template")
|
||||||
|
if (boxes.length < 1) {
|
||||||
|
// no translation needed, hide the controls
|
||||||
|
const controlBox = document.querySelector('.d-l10n-control-box')
|
||||||
|
if (controlBox) {
|
||||||
|
controlBox.style.display = 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const knownTranslations = {}
|
const knownTranslations = {}
|
||||||
|
|
||||||
@ -102,7 +173,7 @@ function processTranslationBoxes() {
|
|||||||
const isUntranslatable = box.getAttribute('data-untranslatable') === 'true'
|
const isUntranslatable = box.getAttribute('data-untranslatable') === 'true'
|
||||||
|
|
||||||
if (originalValue == null || originalValue.length < 1) {
|
if (originalValue == null || originalValue.length < 1) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
knownTranslations[key] = {
|
knownTranslations[key] = {
|
||||||
@ -115,9 +186,10 @@ function processTranslationBoxes() {
|
|||||||
isManuscript: isManuscript,
|
isManuscript: isManuscript,
|
||||||
isUntranslatable: isUntranslatable
|
isUntranslatable: isUntranslatable
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
const currentPreferredTranslation = getPreferredTranslation()
|
const currentPreferredTranslation = getPreferredTranslation()
|
||||||
|
const currentPreferredAnnotation = getPreferredAnnotation()
|
||||||
|
|
||||||
// remove already generated boxes
|
// remove already generated boxes
|
||||||
const generatedBoxes = document.querySelectorAll(".d-l10n-generated")
|
const generatedBoxes = document.querySelectorAll(".d-l10n-generated")
|
||||||
@ -129,13 +201,15 @@ function processTranslationBoxes() {
|
|||||||
boxes.forEach((box) => {
|
boxes.forEach((box) => {
|
||||||
const key = box.innerHTML
|
const key = box.innerHTML
|
||||||
const translation = knownTranslations[key]
|
const translation = knownTranslations[key]
|
||||||
|
const isRefernece = box.getAttribute('data-ref') != null
|
||||||
if (translation == null) {
|
if (translation == null) {
|
||||||
return;
|
box.insertAdjacentHTML('afterend', `<span class="d-l10n-translated-error">Missing translation for: ${key}</span>`)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (translation.isUntranslatable) {
|
if (translation.isUntranslatable) {
|
||||||
box.innerHTML = `<em>${translation.original}</em>`
|
box.insertAdjacentHTML('afterend', `<span class="d-l10n-translated-untranslatable">${translation.original}</span>`)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let preferredTranslation
|
let preferredTranslation
|
||||||
@ -152,7 +226,7 @@ function processTranslationBoxes() {
|
|||||||
if (isCjkContext(preferredTranslation)) {
|
if (isCjkContext(preferredTranslation)) {
|
||||||
preferredTranslation = `<span class="d-l10n-translated-entity-name-cjk">${preferredTranslation}</span>`
|
preferredTranslation = `<span class="d-l10n-translated-entity-name-cjk">${preferredTranslation}</span>`
|
||||||
} else {
|
} else {
|
||||||
preferredTranslation = `<span class="d-l10n-translated-entity-name">${preferredTranslation}</span>`
|
preferredTranslation = `<span class="d-l10n-translated-entity-name d-l10n-translated-non-cjk">${preferredTranslation}</span>`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +234,7 @@ function processTranslationBoxes() {
|
|||||||
if (isCjkContext(preferredTranslation)) {
|
if (isCjkContext(preferredTranslation)) {
|
||||||
preferredTranslation = `<span class="d-l10n-translated-manuscript-name-cjk">${preferredTranslation}</span>`
|
preferredTranslation = `<span class="d-l10n-translated-manuscript-name-cjk">${preferredTranslation}</span>`
|
||||||
} else {
|
} else {
|
||||||
preferredTranslation = `<span class="d-l10n-translated-manuscript-name">${preferredTranslation}</span>`
|
preferredTranslation = `<i class="d-l10n-translated-manuscript-name d-l10n-translated-non-cjk">${preferredTranslation}</i>`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,15 +242,26 @@ function processTranslationBoxes() {
|
|||||||
preferredTranslation = `<ruby>${preferredTranslation}<rt>${translation.ruby}</rt></ruby>`
|
preferredTranslation = `<ruby>${preferredTranslation}<rt>${translation.ruby}</rt></ruby>`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPreferredTranslation === 'original') {
|
if (isRefernece || currentPreferredTranslation === 'original') {
|
||||||
box.insertAdjacentHTML('afterend', `<span class="d-l10n-generated d-l10n-translated-original">${translation.original}</span>`)
|
box.insertAdjacentHTML('afterend', `<span class="d-l10n-generated d-l10n-translated-reference">${preferredTranslation}</span>`)
|
||||||
} else {
|
} else {
|
||||||
|
if (currentPreferredAnnotation === 'parenthesis') {
|
||||||
|
preferredTranslation = processInlineAnnotation(box, preferredTranslation)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPreferredAnnotation === 'ruby') {
|
||||||
|
preferredTranslation = processRubyAnnotation(box, preferredTranslation)
|
||||||
|
}
|
||||||
|
|
||||||
box.insertAdjacentHTML('afterend', `<span class="d-l10n-generated d-l10n-translated" title="${translation.original}">${preferredTranslation}</span>`)
|
box.insertAdjacentHTML('afterend', `<span class="d-l10n-generated d-l10n-translated" title="${translation.original}">${preferredTranslation}</span>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
box.style.display = 'none'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", () => {
|
window.addEventListener("load", () => {
|
||||||
|
setupControls()
|
||||||
processColorBoxes()
|
processColorBoxes()
|
||||||
processTranslationBoxes()
|
processTranslationBoxes()
|
||||||
});
|
})
|
||||||
|
@ -143,5 +143,62 @@ function d_l10n_color_shortcode($attr = array(), $content = null, $tag = ''): ?s
|
|||||||
return '<span class="d-l10n-color" data-color="' . $color . '">' . $content . '</span>';
|
return '<span class="d-l10n-color" data-color="' . $color . '">' . $content . '</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function d_l10n_add_translation_controls($content): string
|
||||||
|
{
|
||||||
|
$controlHtml = <<<HTML
|
||||||
|
<div class="d-l10n-control-box">
|
||||||
|
<div class="d-l10n-control-box-item">
|
||||||
|
<label for="d-l10n-translation-mode" class="d-l10n-control-box-item-label">翻译模式</label>
|
||||||
|
<select id="d-l10n-translation-mode">
|
||||||
|
<option value="writer">使用作者翻译</option>
|
||||||
|
<option value="canonical">使用共识性翻译</option>
|
||||||
|
<option value="original">显示原文</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<span class="d-l10n-control-box-vertical-divider"></span>
|
||||||
|
<div class="d-l10n-control-box-item">
|
||||||
|
<label for="d-l10n-annotation-mode" class="d-l10n-control-box-item-label">注释模式</label>
|
||||||
|
<select id="d-l10n-annotation-mode">
|
||||||
|
<option value="hide">不显示</option>
|
||||||
|
<option value="parenthesis">括号内显示原文</option>
|
||||||
|
<option value="ruby">注音形式显示原文</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
|
||||||
|
$controlHtmlEn = <<<HTML
|
||||||
|
<div class="d-l10n-control-box">
|
||||||
|
<div class="d-l10n-control-box-item">
|
||||||
|
<label for="d-l10n-translation-mode" class="d-l10n-control-box-item-label">Translation Mode</label>
|
||||||
|
<select id="d-l10n-translation-mode">
|
||||||
|
<option value="writer">Use Writer's Translation</option>
|
||||||
|
<option value="canonical">Use Canonical Translation</option>
|
||||||
|
<option value="original">Show Original</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<span class="d-l10n-control-box-vertical-divider"></span>
|
||||||
|
<div class="d-l10n-control-box-item">
|
||||||
|
<label for="d-l10n-annotation-mode" class="d-l10n-control-box-item-label">Annotation Mode</label>
|
||||||
|
<select id="d-l10n-annotation-mode">
|
||||||
|
<option value="hide">Hide</option>
|
||||||
|
<option value="parenthesis">Append Original in Parentheses</option>
|
||||||
|
<option value="ruby">Show Original in Ruby</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
|
||||||
|
$lang = get_bloginfo('language');
|
||||||
|
if (str_contains($lang, 'zh')) {
|
||||||
|
$content = $controlHtml . $content;
|
||||||
|
} else {
|
||||||
|
$content = $controlHtmlEn . $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
add_action('init', 'd_l10n_add_shortcodes');
|
add_action('init', 'd_l10n_add_shortcodes');
|
||||||
add_action('init', 'd_l10n_enque_assets');
|
add_action('init', 'd_l10n_enque_assets');
|
||||||
|
add_filter('the_content', 'd_l10n_add_translation_controls');
|
||||||
|
Loading…
Reference in New Issue
Block a user