feat: PDF text editor internationalization

This commit is contained in:
alam00000 committed 2026-08-22 14:00:07 +05:30
1 parent 0f65fdb2f4
commit 7f6bebf21f
27 files changed
+2936 -127

No files matched your search

+17 -2
View File
@@ -9092,7 +9092,15 @@ async function saveFile() {
a.click();
URL.revokeObjectURL(a.href);
state.dirty = false;
toast('Saved ' + ((bytes.length / 1024) | 0) + ' KB');
const savedKb = (bytes.length / 1024) | 0;
if (onSaved) onSaved(savedKb, state.fileName);
else toast('Saved ' + savedKb + ' KB');
}
let onSaved = null;
function setOnSaved(fn) {
onSaved = typeof fn === 'function' ? fn : null;
}
function wireUI() {
@@ -9975,4 +9983,11 @@ async function addImageFromFile(file) {
} else if (state.undo.length) state.undo.pop();
}
export { openFile, engineReady, setZoom, getZoom, getDocDescription };
export {
openFile,
engineReady,
setZoom,
getZoom,
getDocDescription,
setOnSaved,
};
+7
View File
@@ -299,6 +299,13 @@ export function scriptFallbackFamilies(cps) {
],
[[[0x10a0, 0x10ff]], ['Noto Sans Georgian', 'Sylfaen', 'Arial Unicode MS']],
[[[0x1200, 0x137f]], ['Kefa', 'Nyala', 'Noto Sans Ethiopic']],
[
[[0x0f00, 0x0fff]],
['Kailasa', 'Microsoft Himalaya', 'Noto Sans Tibetan'],
],
[[[0x13a0, 0x13ff]], ['Plantagenet Cherokee', 'Noto Sans Cherokee']],
[[[0x0700, 0x074f]], ['Noto Sans Syriac', 'Estrangelo Edessa']],
[[[0x0780, 0x07bf]], ['Noto Sans Thaana', 'MV Boli']],
];
const out = [];
for (const cp of cps) {
+20 -4
View File
@@ -1,6 +1,7 @@
import '@phosphor-icons/web/regular';
import { createIcons, icons } from 'lucide';
import { showAlert, showLoader, hideLoader } from '../ui.js';
import { t } from '../i18n/i18n';
import { batchDecryptIfNeeded } from '../utils/password-prompt.js';
import { setupFormatDock, setupFindSheet } from './edit-pdf-text-dock';
@@ -274,6 +275,7 @@ interface EditorAppModule {
setZoom: (z: number) => void;
getZoom: () => number;
getDocDescription: () => DocDescription;
setOnSaved: (fn: ((kb: number, fileName: string) => void) | null) => void;
}
function relocateAddText() {
@@ -398,6 +400,12 @@ function setupDocPanel() {
}
let appModule: EditorAppModule | null = null;
function closeEditor() {
document.getElementById('text-editor-app')?.setAttribute('hidden', '');
document.getElementById('uploader')?.classList.remove('hidden');
document.getElementById('tool-landing')?.classList.remove('hidden');
}
let launching = false;
function fitMobileWidth() {
@@ -428,6 +436,16 @@ async function launchEditor(file: File) {
document.getElementById('text-editor-app')?.removeAttribute('hidden');
if (!appModule) {
appModule = (await import('../editcore/app.js')) as EditorAppModule;
appModule.setOnSaved((kb) => {
showAlert(
t('common.success'),
t('tools:editPdfText.saved', { size: kb }),
'success',
() => {
closeEditor();
}
);
});
relocateAddText();
setupDocPanel();
setupEditMenu();
@@ -442,10 +460,8 @@ async function launchEditor(file: File) {
if (window.matchMedia('(max-width: 768px)').matches) fitMobileWidth();
} catch (error) {
console.error('Error loading PDF Text Editor:', error);
showAlert('Error', 'Failed to load the PDF Text Editor.');
document.getElementById('text-editor-app')?.setAttribute('hidden', '');
document.getElementById('uploader')?.classList.remove('hidden');
document.getElementById('tool-landing')?.classList.remove('hidden');
showAlert(t('common.error'), t('tools:editPdfText.failedToLoad'));
closeEditor();
} finally {
hideLoader();
launching = false;
Binary file not shown.
+518 -99
View File
@@ -109,8 +109,8 @@
Edit PDF Text
</h1>
<p class="text-gray-400 mb-6" data-i18n="tools:editPdfText.subtitle">
Click any paragraph and edit it in place with live reflow. Move and
restyle text, images, and shapes — then save a clean PDF.
Click any paragraph and edit it in place with live reflow, fonts, and
styling.
</p>
<div
@@ -158,7 +158,12 @@
1
</div>
<div class="flex-1">
<h3 class="text-lg font-semibold text-white mb-1">Upload PDF</h3>
<h3
class="text-lg font-semibold text-white mb-1"
data-i18n="tools:editPdfText.howToUpload"
>
Upload PDF
</h3>
<p class="text-gray-400">
Select or drag and drop the PDF whose text you want to edit
</p>
@@ -171,7 +176,10 @@
2
</div>
<div class="flex-1">
<h3 class="text-lg font-semibold text-white mb-1">
<h3
class="text-lg font-semibold text-white mb-1"
data-i18n="tools:editPdfText.howToClick"
>
Click a Paragraph
</h3>
<p class="text-gray-400">
@@ -187,7 +195,10 @@
3
</div>
<div class="flex-1">
<h3 class="text-lg font-semibold text-white mb-1">
<h3
class="text-lg font-semibold text-white mb-1"
data-i18n="tools:editPdfText.howToRestyle"
>
Restyle Anything
</h3>
<p class="text-gray-400">
@@ -203,7 +214,12 @@
4
</div>
<div class="flex-1">
<h3 class="text-lg font-semibold text-white mb-1">Save</h3>
<h3
class="text-lg font-semibold text-white mb-1"
data-i18n="common.save"
>
Save
</h3>
<p class="text-gray-400">
Download a clean PDF with your edits baked in — everything stays
on your device
@@ -225,15 +241,33 @@
href="pdf-editor.html"
class="block bg-gray-800 p-4 rounded-lg hover:bg-gray-700 transition-colors border border-gray-700"
>
<h3 class="text-white font-semibold mb-1">PDF Editor</h3>
<p class="text-gray-400 text-sm">Annotate and mark up PDFs</p>
<h3
class="text-white font-semibold mb-1"
data-i18n="tools:pdfEditor.name"
>
PDF Editor
</h3>
<p
class="text-gray-400 text-sm"
data-i18n="tools:editPdfText.relatedPdfEditor"
>
Annotate and mark up PDFs
</p>
</a>
<a
href="sign-pdf.html"
class="block bg-gray-800 p-4 rounded-lg hover:bg-gray-700 transition-colors border border-gray-700"
>
<h3 class="text-white font-semibold mb-1">Sign PDF</h3>
<p class="text-gray-400 text-sm">
<h3
class="text-white font-semibold mb-1"
data-i18n="tools:signPdf.name"
>
Sign PDF
</h3>
<p
class="text-gray-400 text-sm"
data-i18n="tools:editPdfText.relatedSignPdf"
>
Draw, type or upload a signature
</p>
</a>
@@ -241,29 +275,69 @@
href="add-watermark.html"
class="block bg-gray-800 p-4 rounded-lg hover:bg-gray-700 transition-colors border border-gray-700"
>
<h3 class="text-white font-semibold mb-1">Add Watermark</h3>
<p class="text-gray-400 text-sm">Stamp text or images</p>
<h3
class="text-white font-semibold mb-1"
data-i18n="tools:addWatermark.name"
>
Add Watermark
</h3>
<p
class="text-gray-400 text-sm"
data-i18n="tools:editPdfText.relatedWatermark"
>
Stamp text or images
</p>
</a>
<a
href="add-stamps.html"
class="block bg-gray-800 p-4 rounded-lg hover:bg-gray-700 transition-colors border border-gray-700"
>
<h3 class="text-white font-semibold mb-1">Add Stamps</h3>
<p class="text-gray-400 text-sm">Place stamps on pages</p>
<h3
class="text-white font-semibold mb-1"
data-i18n="tools:addStamps.name"
>
Add Stamps
</h3>
<p
class="text-gray-400 text-sm"
data-i18n="tools:editPdfText.relatedStamps"
>
Place stamps on pages
</p>
</a>
<a
href="compress-pdf.html"
class="block bg-gray-800 p-4 rounded-lg hover:bg-gray-700 transition-colors border border-gray-700"
>
<h3 class="text-white font-semibold mb-1">Compress PDF</h3>
<p class="text-gray-400 text-sm">Shrink the file size</p>
<h3
class="text-white font-semibold mb-1"
data-i18n="tools:compressPdf.name"
>
Compress PDF
</h3>
<p
class="text-gray-400 text-sm"
data-i18n="tools:editPdfText.relatedCompress"
>
Shrink the file size
</p>
</a>
<a
href="organize-pdf.html"
class="block bg-gray-800 p-4 rounded-lg hover:bg-gray-700 transition-colors border border-gray-700"
>
<h3 class="text-white font-semibold mb-1">Organize PDF</h3>
<p class="text-gray-400 text-sm">Reorder and manage pages</p>
<h3
class="text-white font-semibold mb-1"
data-i18n="tools:editPdfText.relatedOrganizeName"
>
Organize PDF
</h3>
<p
class="text-gray-400 text-sm"
data-i18n="tools:editPdfText.relatedOrganize"
>
Reorder and manage pages
</p>
</a>
</div>
</section>
@@ -321,20 +395,52 @@
<div id="text-editor-app" hidden>
<div id="toolbar">
<div class="tgroup">
<button id="exitEditor" class="btn icon" title="Back to upload">
<button
id="exitEditor"
class="btn icon"
title="Back to upload"
data-i18n-title="tools:editPdfText.tipBackToUpload"
>
<i class="ph ph-arrow-left"></i>
</button>
<label class="btn" for="file" title="Open another PDF">
<i class="ph ph-folder-open"></i><span>Open</span>
<label
class="btn"
for="file"
title="Open another PDF"
data-i18n-title="tools:editPdfText.tipOpenAnotherPdf"
>
<i class="ph ph-folder-open"></i
><span data-i18n="tools:editPdfText.open">Open</span>
</label>
<input id="file" type="file" accept="application/pdf" hidden />
<button id="save" class="btn" disabled title="Export (⌘S)">
<i class="ph ph-export"></i><span>Export</span>
<button
id="save"
class="btn"
disabled
title="Export (⌘S)"
data-i18n-title="tools:editPdfText.tipExportS"
>
<i class="ph ph-export"></i
><span data-i18n="tools:editPdfText.export">Export</span>
</button>
<button id="undo" class="btn icon" disabled hidden title="Undo (⌘Z)">
<button
id="undo"
class="btn icon"
disabled
hidden
title="Undo (⌘Z)"
data-i18n-title="tools:editPdfText.tipUndoZ"
>
<i class="ph ph-arrow-u-up-left"></i>
</button>
<button id="redo" class="btn icon" disabled hidden title="Redo (⇧⌘Z)">
<button
id="redo"
class="btn icon"
disabled
hidden
title="Redo (⇧⌘Z)"
data-i18n-title="tools:editPdfText.tipRedoZ"
>
<i class="ph ph-arrow-u-up-right"></i>
</button>
</div>
@@ -343,10 +449,16 @@
class="docname"
hidden
title="File details"
data-i18n-title="tools:editPdfText.tipFileDetails"
></button>
<span class="sep"></span>
<div id="tools" class="segmented">
<button data-tool="edit" class="on" title="Edit existing content">
<button
data-tool="edit"
class="on"
title="Edit existing content"
data-i18n-title="tools:editPdfText.tipEditExistingContent"
>
<i class="ph ph-pencil-simple"></i
><span id="editLabel">Edit All</span
><i class="ph ph-caret-down editcaret"></i>
@@ -355,14 +467,32 @@
id="editScope"
hidden
title="What the Edit tool touches — narrow the scope on busy pages"
data-i18n-title="tools:editPdfText.tipWhatTheEditToolTouchesNarrowTheScopeOnBus"
>
<option value="all" selected>All</option>
<option value="text">Text</option>
<option value="image">Images</option>
<option value="shape">Shapes</option>
<option
value="all"
selected
data-i18n="tools:editPdfText.filterAll"
>
All
</option>
<option value="text" data-i18n="tools:editPdfText.filterText">
Text
</option>
<option value="image" data-i18n="tools:editPdfText.filterImages">
Images
</option>
<option value="shape" data-i18n="tools:editPdfText.filterShapes">
Shapes
</option>
</select>
<button data-tool="addText" title="Click the page to add a text box">
<i class="ph ph-textbox"></i><span>Add Text</span>
<button
data-tool="addText"
title="Click the page to add a text box"
data-i18n-title="tools:editPdfText.tipClickThePageToAddATextBox"
>
<i class="ph ph-textbox"></i
><span data-i18n="tools:editPdfText.addText">Add Text</span>
</button>
</div>
<input id="imgFile" type="file" accept="image/*" hidden />
@@ -370,8 +500,14 @@
<label class="chk"
><input id="spellchk" type="checkbox" /> Spelling</label
>
<select id="spellLang" title="Spell-check language">
<option value="">Auto</option>
<select
id="spellLang"
title="Spell-check language"
data-i18n-title="tools:editPdfText.tipSpellCheckLanguage"
>
<option value="" data-i18n="tools:editPdfText.langAuto">
Auto
</option>
<option value="en">English (US)</option>
<option value="en-GB">English (UK)</option>
<option value="de">Deutsch</option>
@@ -388,10 +524,20 @@
</div>
<span id="info" class="info"></span>
<div class="tgroup toolright">
<button id="find" class="btn icon" title="Find &amp; replace">
<button
id="find"
class="btn icon"
title="Find &amp; replace"
data-i18n-title="tools:editPdfText.tipFindAndReplace"
>
<i class="ph ph-magnifying-glass"></i>
</button>
<button id="addImage" class="btn icon" title="Add an image">
<button
id="addImage"
class="btn icon"
title="Add an image"
data-i18n-title="tools:editPdfText.tipAddAnImage"
>
<i class="ph ph-image"></i>
</button>
<button
@@ -399,6 +545,7 @@
class="btn icon"
hidden
title="Copy this page's text in reading order"
data-i18n-title="tools:editPdfText.tipCopyThisPageSTextInReadingOrder"
>
<i class="ph ph-clipboard-text"></i>
</button>
@@ -407,6 +554,7 @@
class="btn icon"
hidden
title="Check the spelling of this page"
data-i18n-title="tools:editPdfText.tipCheckTheSpellingOfThisPage"
>
<i class="ph ph-text-aa"></i>
</button>
@@ -415,6 +563,7 @@
id="toggleInspector"
class="btn icon"
title="Show or hide the format panel"
data-i18n-title="tools:editPdfText.tipShowOrHideTheFormatPanel"
>
<i class="ph ph-sidebar-simple"></i>
</button>
@@ -424,15 +573,44 @@
<div id="spellbar" hidden>
<i class="ph ph-text-aa barlead"></i>
<span id="spellWord" class="info">—</span>
<input id="spellFix" placeholder="Replace with" />
<button id="spellChange" class="btn">Change</button>
<button id="spellIgnore" class="btn">Ignore</button>
<button id="spellAdd" class="btn" title="Add to your dictionary">
<input
id="spellFix"
placeholder="Replace with"
data-i18n-placeholder="tools:editPdfText.phReplaceWith"
/>
<button
id="spellChange"
class="btn"
data-i18n="tools:editPdfText.change"
>
Change
</button>
<button
id="spellIgnore"
class="btn"
data-i18n="tools:editPdfText.ignore"
>
Ignore
</button>
<button
id="spellAdd"
class="btn"
title="Add to your dictionary"
data-i18n="common.add"
data-i18n-title="tools:editPdfText.tipAddToYourDictionary"
>
Add
</button>
<button id="spellNext" class="btn">Next</button>
<button id="spellNext" class="btn" data-i18n="tools:editPdfText.next">
Next
</button>
<span id="spellStatus" class="info"></span>
<button id="spellDone" class="btn icon" title="Close">
<button
id="spellDone"
class="btn icon"
title="Close"
data-i18n-title="tools:editPdfText.tipClose"
>
<i class="ph ph-x"></i>
</button>
</div>
@@ -444,23 +622,58 @@
><i class="ph ph-magnifying-glass barlead"></i> Find &amp;
Replace</span
>
<button id="findDone" class="btn icon" title="Close">
<button
id="findDone"
class="btn icon"
title="Close"
data-i18n-title="tools:editPdfText.tipClose"
>
<i class="ph ph-x"></i>
</button>
</div>
<div class="findfield">
<input id="findText" placeholder="Find" />
<button id="findPrev" class="btn icon" title="Previous match">
<input
id="findText"
placeholder="Find"
data-i18n-placeholder="tools:editPdfText.phFind"
/>
<button
id="findPrev"
class="btn icon"
title="Previous match"
data-i18n-title="tools:editPdfText.tipPreviousMatch"
>
<i class="ph ph-caret-up"></i>
</button>
<button id="findNext" class="btn icon" title="Next match">
<button
id="findNext"
class="btn icon"
title="Next match"
data-i18n-title="tools:editPdfText.tipNextMatch"
>
<i class="ph ph-caret-down"></i>
</button>
</div>
<input id="replText" placeholder="Replace with" />
<input
id="replText"
placeholder="Replace with"
data-i18n-placeholder="tools:editPdfText.phReplaceWith"
/>
<div class="findrow">
<button id="replOne" class="btn grow">Replace</button>
<button id="replAll" class="btn grow">Replace All</button>
<button
id="replOne"
class="btn grow"
data-i18n="tools:editPdfText.replace"
>
Replace
</button>
<button
id="replAll"
class="btn grow"
data-i18n="tools:editPdfText.replaceAll"
>
Replace All
</button>
</div>
<label class="chk"
><input id="caseSens" type="checkbox" /> Match case</label
@@ -476,8 +689,15 @@
<div id="stage">
<div id="empty">
<h1 data-i18n="tools:editPdfText.name">Edit PDF Text</h1>
<p>Open a PDF to edit its text, images and shapes.</p>
<label class="btn big" for="file">Choose a PDF…</label>
<p data-i18n="tools:editPdfText.emptyState">
Open a PDF to edit its text, images and shapes.
</p>
<label
class="btn big"
for="file"
data-i18n="tools:editPdfText.choosePdf"
>Choose a PDF…</label
>
<p class="hint">
Everything runs locally in your browser — nothing is uploaded.
</p>
@@ -495,6 +715,7 @@
class="btn icon objbtn"
hidden
title="Rotate left 90°"
data-i18n-title="tools:editPdfText.tipRotateLeft90"
>
<i class="ph ph-arrow-counter-clockwise"></i>
</button>
@@ -503,6 +724,7 @@
class="btn icon objbtn"
hidden
title="Rotate right 90°"
data-i18n-title="tools:editPdfText.tipRotateRight90"
>
<i class="ph ph-arrow-clockwise"></i>
</button>
@@ -511,6 +733,7 @@
class="btn icon objbtn"
hidden
title="Flip horizontal"
data-i18n-title="tools:editPdfText.tipFlipHorizontal"
>
<i class="ph ph-flip-horizontal"></i>
</button>
@@ -519,6 +742,7 @@
class="btn icon objbtn"
hidden
title="Flip vertical"
data-i18n-title="tools:editPdfText.tipFlipVertical"
>
<i class="ph ph-flip-vertical"></i>
</button>
@@ -528,6 +752,7 @@
class="btn icon objbtn"
hidden
title="Replace this image, keeping its placement"
data-i18n-title="tools:editPdfText.tipReplaceThisImageKeepingItsPlacement"
>
<i class="ph ph-image-square"></i>
</button>
@@ -544,6 +769,7 @@
class="btn icon objbtn"
hidden
title="Alternate text for accessibility (tagged PDFs)"
data-i18n-title="tools:editPdfText.tipAlternateTextForAccessibilityTaggedPdfs"
>
<i class="ph ph-tag"></i>
</button>
@@ -554,6 +780,7 @@
class="btn icon objbtn"
hidden
title="Bring to front"
data-i18n-title="tools:editPdfText.tipBringToFront"
>
<i class="ph ph-arrow-line-up"></i>
</button>
@@ -562,39 +789,84 @@
class="btn icon objbtn"
hidden
title="Send to back"
data-i18n-title="tools:editPdfText.tipSendToBack"
>
<i class="ph ph-arrow-line-down"></i>
</button>
<button id="dupe" class="btn icon objbtn" hidden title="Duplicate">
<button
id="dupe"
class="btn icon objbtn"
hidden
title="Duplicate"
data-i18n-title="tools:editPdfText.tipDuplicate"
>
<i class="ph ph-copy"></i>
</button>
<button id="del" class="btn icon objbtn" hidden title="Delete">
<button
id="del"
class="btn icon objbtn"
hidden
title="Delete"
data-i18n-title="tools:editPdfText.tipDelete"
>
<i class="ph ph-trash"></i>
</button>
</div>
<div id="alignTools" class="segmented" hidden>
<button data-al="left" title="Align left edges">
<button
data-al="left"
title="Align left edges"
data-i18n-title="tools:editPdfText.tipAlignLeftEdges"
>
<i class="ph ph-align-left"></i>
</button>
<button data-al="hcenter" title="Align horizontal centers">
<button
data-al="hcenter"
title="Align horizontal centers"
data-i18n-title="tools:editPdfText.tipAlignHorizontalCenters"
>
<i class="ph ph-align-center-horizontal"></i>
</button>
<button data-al="right" title="Align right edges">
<button
data-al="right"
title="Align right edges"
data-i18n-title="tools:editPdfText.tipAlignRightEdges"
>
<i class="ph ph-align-right"></i>
</button>
<button data-al="top" title="Align tops">
<button
data-al="top"
title="Align tops"
data-i18n-title="tools:editPdfText.tipAlignTops"
>
<i class="ph ph-align-top"></i>
</button>
<button data-al="vcenter" title="Align vertical centers">
<button
data-al="vcenter"
title="Align vertical centers"
data-i18n-title="tools:editPdfText.tipAlignVerticalCenters"
>
<i class="ph ph-align-center-vertical"></i>
</button>
<button data-al="bottom" title="Align bottoms">
<button
data-al="bottom"
title="Align bottoms"
data-i18n-title="tools:editPdfText.tipAlignBottoms"
>
<i class="ph ph-align-bottom"></i>
</button>
<button data-al="disth" title="Distribute horizontally">
<button
data-al="disth"
title="Distribute horizontally"
data-i18n-title="tools:editPdfText.tipDistributeHorizontally"
>
<i class="ph ph-columns"></i>
</button>
<button data-al="distv" title="Distribute vertically">
<button
data-al="distv"
title="Distribute vertically"
data-i18n-title="tools:editPdfText.tipDistributeVertically"
>
<i class="ph ph-rows"></i>
</button>
</div>
@@ -602,7 +874,7 @@
<aside id="inspector" hidden>
<h2><i class="ph ph-sliders-horizontal"></i> Format</h2>
<h3 class="sect">Font</h3>
<h3 class="sect" data-i18n="tools:editPdfText.font">Font</h3>
<div class="row">
<select id="fFamily"></select>
<input
@@ -613,6 +885,7 @@
step="1"
class="num"
title="Font size"
data-i18n-title="tools:editPdfText.tipFontSize"
/>
</div>
<div class="row">
@@ -620,11 +893,15 @@
id="sysFonts"
class="btn grow"
title="List fonts installed on this device (Chromium)"
data-i18n-title="tools:editPdfText.tipListFontsInstalledOnThisDeviceChromium"
>
<i class="ph ph-download-simple"></i><span>System fonts</span>
<i class="ph ph-download-simple"></i
><span data-i18n="tools:editPdfText.systemFonts"
>System fonts</span
>
</button>
</div>
<h3 class="sect">Color</h3>
<h3 class="sect" data-i18n="tools:editPdfText.color">Color</h3>
<div class="row swatchrow">
<div class="swatches" id="fSwatches"></div>
<input
@@ -632,57 +909,112 @@
type="color"
value="#000000"
title="Custom text color"
data-i18n-title="tools:editPdfText.tipCustomTextColor"
/>
</div>
<h3 class="sect">Alignment</h3>
<h3 class="sect" data-i18n="tools:editPdfText.alignment">
Alignment
</h3>
<div class="row">
<div class="segmented small grow" id="fAlign">
<button data-a="0" title="Align left">
<button
data-a="0"
title="Align left"
data-i18n-title="tools:editPdfText.tipAlignLeft"
>
<i class="ph ph-text-align-left"></i>
</button>
<button data-a="1" title="Align center">
<button
data-a="1"
title="Align center"
data-i18n-title="tools:editPdfText.tipAlignCenter"
>
<i class="ph ph-text-align-center"></i>
</button>
<button data-a="2" title="Align right">
<button
data-a="2"
title="Align right"
data-i18n-title="tools:editPdfText.tipAlignRight"
>
<i class="ph ph-text-align-right"></i>
</button>
<button data-a="3" title="Justify">
<button
data-a="3"
title="Justify"
data-i18n-title="tools:editPdfText.tipJustify"
>
<i class="ph ph-text-align-justify"></i>
</button>
</div>
</div>
<h3 class="sect">Style</h3>
<h3 class="sect" data-i18n="tools:editPdfText.style">Style</h3>
<div class="row toggles" id="fToggles">
<button data-t="bold" title="Bold">
<button
data-t="bold"
title="Bold"
data-i18n-title="tools:editPdfText.tipBold"
>
<i class="ph ph-text-b"></i>
</button>
<button data-t="italic" title="Italic">
<button
data-t="italic"
title="Italic"
data-i18n-title="tools:editPdfText.tipItalic"
>
<i class="ph ph-text-italic"></i>
</button>
<button data-t="underline" title="Underline">
<button
data-t="underline"
title="Underline"
data-i18n-title="tools:editPdfText.tipUnderline"
>
<i class="ph ph-text-underline"></i>
</button>
<button data-t="strike" title="Strikethrough">
<button
data-t="strike"
title="Strikethrough"
data-i18n-title="tools:editPdfText.tipStrikethrough"
>
<i class="ph ph-text-strikethrough"></i>
</button>
<button data-t="sup" title="Superscript">
<button
data-t="sup"
title="Superscript"
data-i18n-title="tools:editPdfText.tipSuperscript"
>
<i class="ph ph-text-superscript"></i>
</button>
<button data-t="sub" title="Subscript">
<button
data-t="sub"
title="Subscript"
data-i18n-title="tools:editPdfText.tipSubscript"
>
<i class="ph ph-text-subscript"></i>
</button>
</div>
<h3 class="sect">Lists</h3>
<h3 class="sect" data-i18n="tools:editPdfText.lists">Lists</h3>
<div class="row">
<div class="segmented small" id="fList">
<button data-l="bullet" title="Toggle bulleted item">
<button
data-l="bullet"
title="Toggle bulleted item"
data-i18n-title="tools:editPdfText.tipToggleBulletedItem"
>
<i class="ph ph-list-bullets"></i>
</button>
<button data-l="number" title="Toggle numbered item">
<button
data-l="number"
title="Toggle numbered item"
data-i18n-title="tools:editPdfText.tipToggleNumberedItem"
>
<i class="ph ph-list-numbers"></i>
</button>
</div>
<select id="fMarkerStyle" title="Numbered-list marker style">
<select
id="fMarkerStyle"
title="Numbered-list marker style"
data-i18n-title="tools:editPdfText.tipNumberedListMarkerStyle"
>
<option value="1">1. 2. 3.</option>
<option value="a">a. b. c.</option>
<option value="A">A. B. C.</option>
@@ -690,21 +1022,30 @@
<option value="I">I. II. III.</option>
</select>
<div class="segmented small" id="fLevel">
<button data-lv="-1" title="Decrease list indent (⇧Tab)">
<button
data-lv="-1"
title="Decrease list indent (⇧Tab)"
data-i18n-title="tools:editPdfText.tipDecreaseListIndentTab"
>
<i class="ph ph-text-outdent"></i>
</button>
<button data-lv="1" title="Increase list indent (Tab)">
<button
data-lv="1"
title="Increase list indent (Tab)"
data-i18n-title="tools:editPdfText.tipIncreaseListIndentTab"
>
<i class="ph ph-text-indent"></i>
</button>
</div>
</div>
<h3 class="sect">Outline</h3>
<h3 class="sect" data-i18n="tools:editPdfText.outline">Outline</h3>
<div class="row">
<input
id="fStrokeColor"
type="color"
value="#000000"
title="Text outline color"
data-i18n-title="tools:editPdfText.tipTextOutlineColor"
/>
<input
id="fStrokeW"
@@ -714,9 +1055,10 @@
step="0.1"
class="num"
title="Outline width (0 = none)"
data-i18n-title="tools:editPdfText.tipOutlineWidth0None"
/>
</div>
<h3 class="sect">Spacing</h3>
<h3 class="sect" data-i18n="tools:editPdfText.spacing">Spacing</h3>
<label class="field"
>Line Spacing
<input
@@ -787,21 +1129,45 @@
step="1"
class="num"
/></label>
<h3 class="sect">Direction</h3>
<h3 class="sect" data-i18n="tools:editPdfText.direction">
Direction
</h3>
<div class="row">
<div class="segmented small grow" id="fDir">
<button data-d="0" title="From content">Auto</button>
<button data-d="1" title="Left to right">LTR</button>
<button data-d="2" title="Right to left">RTL</button>
<button
data-d="0"
title="From content"
data-i18n="tools:editPdfText.dirAuto"
data-i18n-title="tools:editPdfText.tipFromContent"
>
Auto
</button>
<button
data-d="1"
title="Left to right"
data-i18n-title="tools:editPdfText.tipLeftToRight"
>
LTR
</button>
<button
data-d="2"
title="Right to left"
data-i18n-title="tools:editPdfText.tipRightToLeft"
>
RTL
</button>
</div>
</div>
<div class="row" id="pStrokeRow" hidden>
<span class="chk">Path stroke</span>
<span class="chk" data-i18n="tools:editPdfText.pathStroke"
>Path stroke</span
>
<input
id="pStrokeColor"
type="color"
value="#000000"
title="Stroke color"
data-i18n-title="tools:editPdfText.tipStrokeColor"
/>
<input
id="pStrokeW"
@@ -811,6 +1177,7 @@
step="0.5"
class="num"
title="Stroke width"
data-i18n-title="tools:editPdfText.tipStrokeWidth"
/>
</div>
</aside>
@@ -818,22 +1185,47 @@
<div id="viewbar">
<div class="vbzoom">
<button id="zoomMenuBtn" class="btn vbzoomlabel" title="Zoom presets">
<button
id="zoomMenuBtn"
class="btn vbzoomlabel"
title="Zoom presets"
data-i18n-title="tools:editPdfText.tipZoomPresets"
>
<span id="zoomLabel" class="label">100%</span
><i class="ph ph-caret-down editcaret"></i>
</button>
<button id="zoomOut" class="btn icon" title="Zoom out">
<button
id="zoomOut"
class="btn icon"
title="Zoom out"
data-i18n-title="tools:editPdfText.tipZoomOut"
>
<i class="ph ph-minus-circle"></i>
</button>
<button id="zoomIn" class="btn icon" title="Zoom in">
<button
id="zoomIn"
class="btn icon"
title="Zoom in"
data-i18n-title="tools:editPdfText.tipZoomIn"
>
<i class="ph ph-plus-circle"></i>
</button>
<button id="zoomFit" class="btn icon" title="Fit page">
<button
id="zoomFit"
class="btn icon"
title="Fit page"
data-i18n-title="tools:editPdfText.tipFitPage"
>
<i class="ph ph-frame-corners"></i>
</button>
</div>
<div class="vbcenter">
<button id="prev" class="btn icon" title="Previous page">
<button
id="prev"
class="btn icon"
title="Previous page"
data-i18n-title="tools:editPdfText.tipPreviousPage"
>
<i class="ph ph-caret-left"></i>
</button>
<span id="pageLabel" class="label">– / –</span>
@@ -844,22 +1236,44 @@
min="1"
step="1"
title="Type a page number and press Enter"
data-i18n-title="tools:editPdfText.tipTypeAPageNumberAndPressEnter"
/>
<span id="pageTotal" class="label pagetotal">/ –</span>
<button id="next" class="btn icon" title="Next page">
<button
id="next"
class="btn icon"
title="Next page"
data-i18n-title="tools:editPdfText.tipNextPage"
>
<i class="ph ph-caret-right"></i>
</button>
</div>
<div class="vbright">
<button id="docInfoBtn" class="btn icon" title="Document properties">
<button
id="docInfoBtn"
class="btn icon"
title="Document properties"
data-i18n-title="tools:editPdfText.tipDocumentProperties"
>
<i class="ph ph-info"></i>
</button>
<button id="vbCollapse" class="btn icon" title="Hide bar">
<button
id="vbCollapse"
class="btn icon"
title="Hide bar"
data-i18n-title="tools:editPdfText.tipHideBar"
>
<i class="ph ph-caret-double-down"></i>
</button>
</div>
</div>
<button id="vbRestore" class="btn icon" hidden title="Show bar">
<button
id="vbRestore"
class="btn icon"
hidden
title="Show bar"
data-i18n-title="tools:editPdfText.tipShowBar"
>
<i class="ph ph-caret-double-up"></i>
</button>
@@ -874,7 +1288,11 @@
class="bg-gray-800 p-8 rounded-lg flex flex-col items-center gap-4 border border-gray-700 shadow-xl"
>
<div class="solid-spinner"></div>
<p id="loader-text" class="text-white text-lg font-medium">
<p
id="loader-text"
class="text-white text-lg font-medium"
data-i18n="loader.processing"
>
Processing...
</p>
</div>
@@ -898,6 +1316,7 @@
<button
id="alert-ok"
class="w-full bg-indigo-600 hover:bg-indigo-700 text-white font-semibold py-2 px-4 rounded-lg transition-colors duration-200"
data-i18n="alert.ok"
>
OK
</button>