autumnnote 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +401 -628
- package/dist/autumnnote.css +169 -0
- package/dist/autumnnote.es.js +3669 -179
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +3668 -178
- package/dist/autumnnote.umd.js.map +1 -1
- package/package.json +3 -2
- package/src/js/Context.js +18 -2
- package/src/js/core/func.js +5 -5
- package/src/js/i18n/de.js +320 -0
- package/src/js/i18n/en.js +328 -0
- package/src/js/i18n/es.js +320 -0
- package/src/js/i18n/fr.js +321 -0
- package/src/js/i18n/index.js +59 -0
- package/src/js/i18n/ja.js +321 -0
- package/src/js/i18n/ko.js +320 -0
- package/src/js/i18n/vi.js +321 -0
- package/src/js/i18n/zh.js +321 -0
- package/src/js/index.js +2 -1
- package/src/js/module/AutoSaveRestore.js +126 -0
- package/src/js/module/BubbleToolbar.js +243 -0
- package/src/js/module/CodeTooltip.js +12 -9
- package/src/js/module/ContextMenu.js +41 -37
- package/src/js/module/EmojiDialog.js +8 -7
- package/src/js/module/FindReplace.js +14 -13
- package/src/js/module/IconDialog.js +14 -13
- package/src/js/module/ImageDialog.js +17 -16
- package/src/js/module/ImageTooltip.js +13 -12
- package/src/js/module/LinkDialog.js +10 -9
- package/src/js/module/LinkTooltip.js +6 -5
- package/src/js/module/MarkdownShortcuts.js +253 -0
- package/src/js/module/Mention.js +337 -0
- package/src/js/module/ShortcutsDialog.js +5 -4
- package/src/js/module/Statusbar.js +6 -5
- package/src/js/module/TableTooltip.js +22 -19
- package/src/js/module/Toolbar.js +21 -15
- package/src/js/module/VideoDialog.js +10 -9
- package/src/js/module/VideoTooltip.js +12 -11
- package/src/js/settings.js +23 -0
- package/src/styles/autumnnote.scss +191 -0
- package/types/index.d.ts +114 -1
package/dist/autumnnote.es.js
CHANGED
|
@@ -96,8 +96,7 @@ function isFunction(val) {
|
|
|
96
96
|
function mergeDeep(target, source) {
|
|
97
97
|
const output = {};
|
|
98
98
|
for (const key of Object.keys(target)) output[key] = Array.isArray(target[key]) ? [...target[key]] : target[key];
|
|
99
|
-
if (isPlainObject(target) && isPlainObject(source)) for (const key of Object.keys(source)) if (isPlainObject(source[key]))
|
|
100
|
-
else output[key] = mergeDeep(target[key], source[key]);
|
|
99
|
+
if (isPlainObject(target) && isPlainObject(source)) for (const key of Object.keys(source)) if (isPlainObject(source[key])) output[key] = mergeDeep(isPlainObject(target[key]) ? target[key] : {}, source[key]);
|
|
101
100
|
else if (Array.isArray(source[key])) output[key] = [...source[key]];
|
|
102
101
|
else output[key] = source[key];
|
|
103
102
|
return output;
|
|
@@ -1443,9 +1442,2713 @@ var defaultOptions = {
|
|
|
1443
1442
|
onDestroy: null,
|
|
1444
1443
|
onCharLimitReached: null,
|
|
1445
1444
|
onWordLimitReached: null,
|
|
1446
|
-
focusColor: null
|
|
1445
|
+
focusColor: null,
|
|
1446
|
+
lang: "en",
|
|
1447
|
+
autoSaveRestore: false,
|
|
1448
|
+
autoSaveRestoreTimeout: 7,
|
|
1449
|
+
onAutoSaveRestore: null,
|
|
1450
|
+
markdownShortcuts: true,
|
|
1451
|
+
bubbleToolbar: false,
|
|
1452
|
+
bubbleToolbarItems: [
|
|
1453
|
+
"bold",
|
|
1454
|
+
"italic",
|
|
1455
|
+
"underline",
|
|
1456
|
+
"link",
|
|
1457
|
+
"foreColor",
|
|
1458
|
+
"removeFormat"
|
|
1459
|
+
],
|
|
1460
|
+
mention: null
|
|
1447
1461
|
};
|
|
1448
1462
|
//#endregion
|
|
1463
|
+
//#region src/js/i18n/en.js
|
|
1464
|
+
/**
|
|
1465
|
+
* en.js - English locale (canonical reference)
|
|
1466
|
+
* All other locales deep-merge against this to fill missing keys.
|
|
1467
|
+
*/
|
|
1468
|
+
/** @type {import('../../../types/index.js').AsnLocale} */
|
|
1469
|
+
var en = {
|
|
1470
|
+
toolbar: {
|
|
1471
|
+
bold: "Bold (Ctrl+B)",
|
|
1472
|
+
italic: "Italic (Ctrl+I)",
|
|
1473
|
+
underline: "Underline (Ctrl+U)",
|
|
1474
|
+
strikethrough: "Strikethrough",
|
|
1475
|
+
superscript: "Superscript",
|
|
1476
|
+
subscript: "Subscript",
|
|
1477
|
+
alignLeft: "Align Left",
|
|
1478
|
+
alignCenter: "Align Center",
|
|
1479
|
+
alignRight: "Align Right",
|
|
1480
|
+
alignJustify: "Justify",
|
|
1481
|
+
ul: "Unordered List",
|
|
1482
|
+
ol: "Ordered List",
|
|
1483
|
+
checklist: "Checklist",
|
|
1484
|
+
indent: "Indent",
|
|
1485
|
+
outdent: "Outdent",
|
|
1486
|
+
undo: "Undo (Ctrl+Z)",
|
|
1487
|
+
redo: "Redo (Ctrl+Y)",
|
|
1488
|
+
hr: "Horizontal Rule",
|
|
1489
|
+
link: "Insert Link",
|
|
1490
|
+
image: "Insert Image",
|
|
1491
|
+
video: "Insert Video",
|
|
1492
|
+
emoji: "Insert Emoji",
|
|
1493
|
+
icon: "Insert FA Icon",
|
|
1494
|
+
table: "Insert Table",
|
|
1495
|
+
fontSize: "Font Size",
|
|
1496
|
+
fontSizePlaceholder: "Size",
|
|
1497
|
+
removeFormat: "Remove Format",
|
|
1498
|
+
direction: "Toggle Text Direction (LTR / RTL)",
|
|
1499
|
+
fontFamily: "Font Family",
|
|
1500
|
+
paragraphStyle: "Paragraph Style",
|
|
1501
|
+
paragraphStylePlaceholder: "Style",
|
|
1502
|
+
lineHeight: "Line Height",
|
|
1503
|
+
lineHeightPlaceholder: "↕ Line",
|
|
1504
|
+
codeview: "HTML Code View",
|
|
1505
|
+
fullscreen: "Fullscreen",
|
|
1506
|
+
shortcuts: "Keyboard Shortcuts (Ctrl+Shift+/)",
|
|
1507
|
+
find: "Find (Ctrl+F)",
|
|
1508
|
+
findReplace: "Find & Replace (Ctrl+H)",
|
|
1509
|
+
inlineCode: "Inline Code (Ctrl+`)",
|
|
1510
|
+
print: "Print",
|
|
1511
|
+
foreColor: "Text Color",
|
|
1512
|
+
backColor: "Highlight Color",
|
|
1513
|
+
chooseTextColor: "Choose text color",
|
|
1514
|
+
chooseHighlightColor: "Choose highlight color",
|
|
1515
|
+
customColor: "Custom color",
|
|
1516
|
+
insertTableLabel: "Insert Table",
|
|
1517
|
+
paragraphItems: {
|
|
1518
|
+
p: "Normal",
|
|
1519
|
+
blockquote: "Quote",
|
|
1520
|
+
pre: "Code"
|
|
1521
|
+
}
|
|
1522
|
+
},
|
|
1523
|
+
linkDialog: {
|
|
1524
|
+
ariaLabel: "Insert link",
|
|
1525
|
+
title: "Insert Link",
|
|
1526
|
+
url: "URL",
|
|
1527
|
+
urlPlaceholder: "https://",
|
|
1528
|
+
displayText: "Display Text",
|
|
1529
|
+
textPlaceholder: "Link text",
|
|
1530
|
+
openInNewTab: "Open in new tab",
|
|
1531
|
+
insertBtn: "Insert",
|
|
1532
|
+
cancelBtn: "Cancel"
|
|
1533
|
+
},
|
|
1534
|
+
imageDialog: {
|
|
1535
|
+
ariaLabel: "Insert image",
|
|
1536
|
+
title: "Insert Image",
|
|
1537
|
+
imageUrl: "Image URL",
|
|
1538
|
+
urlPlaceholder: "https://example.com/image.png",
|
|
1539
|
+
altText: "Alt Text",
|
|
1540
|
+
altPlaceholder: "Describe the image",
|
|
1541
|
+
alignment: "Alignment",
|
|
1542
|
+
alignNone: "None",
|
|
1543
|
+
alignLeft: "Left",
|
|
1544
|
+
alignCenter: "Center",
|
|
1545
|
+
alignRight: "Right",
|
|
1546
|
+
uploadLabel: "Or upload a file",
|
|
1547
|
+
insertBtn: "Insert",
|
|
1548
|
+
cancelBtn: "Cancel"
|
|
1549
|
+
},
|
|
1550
|
+
videoDialog: {
|
|
1551
|
+
ariaLabel: "Insert video",
|
|
1552
|
+
title: "Insert Video",
|
|
1553
|
+
videoUrl: "Video URL",
|
|
1554
|
+
urlPlaceholder: "YouTube, Vimeo, or direct .mp4 URL",
|
|
1555
|
+
widthLabel: "Width (px)",
|
|
1556
|
+
widthPlaceholder: "560",
|
|
1557
|
+
insertBtn: "Insert",
|
|
1558
|
+
cancelBtn: "Cancel",
|
|
1559
|
+
detected: (type) => `Detected: ${type}`,
|
|
1560
|
+
unknownFormat: "Unknown format — will try direct video embed",
|
|
1561
|
+
invalidUrl: "Invalid URL — please enter a valid video link."
|
|
1562
|
+
},
|
|
1563
|
+
emojiDialog: {
|
|
1564
|
+
ariaLabel: "Insert emoji",
|
|
1565
|
+
title: "Insert Emoji",
|
|
1566
|
+
searchPlaceholder: "Search emojis…",
|
|
1567
|
+
all: "All",
|
|
1568
|
+
cancelBtn: "Cancel",
|
|
1569
|
+
close: "Close",
|
|
1570
|
+
categories: {
|
|
1571
|
+
smileys: "Smileys",
|
|
1572
|
+
people: "People",
|
|
1573
|
+
animals: "Animals",
|
|
1574
|
+
food: "Food",
|
|
1575
|
+
travel: "Travel",
|
|
1576
|
+
objects: "Objects",
|
|
1577
|
+
symbols: "Symbols"
|
|
1578
|
+
}
|
|
1579
|
+
},
|
|
1580
|
+
iconDialog: {
|
|
1581
|
+
ariaLabel: "Insert FA icon",
|
|
1582
|
+
title: "Insert FA Icon",
|
|
1583
|
+
searchPlaceholder: "Search icons…",
|
|
1584
|
+
all: "All",
|
|
1585
|
+
style: "Style",
|
|
1586
|
+
size: "Size",
|
|
1587
|
+
color: "Color",
|
|
1588
|
+
useColor: " Use color",
|
|
1589
|
+
selectHint: "Select an icon",
|
|
1590
|
+
insertBtn: "Insert FA Icon",
|
|
1591
|
+
cancelBtn: "Cancel",
|
|
1592
|
+
close: "Close",
|
|
1593
|
+
categories: {
|
|
1594
|
+
popular: "Popular",
|
|
1595
|
+
interface: "Interface",
|
|
1596
|
+
navigation: "Navigation",
|
|
1597
|
+
media: "Media",
|
|
1598
|
+
communication: "Communication",
|
|
1599
|
+
files: "Files",
|
|
1600
|
+
people: "People",
|
|
1601
|
+
objects: "Objects"
|
|
1602
|
+
}
|
|
1603
|
+
},
|
|
1604
|
+
findReplace: {
|
|
1605
|
+
findTitle: "Find",
|
|
1606
|
+
findReplaceTitle: "Find & Replace",
|
|
1607
|
+
findPlaceholder: "Find…",
|
|
1608
|
+
searchAriaLabel: "Search text",
|
|
1609
|
+
caseSensitive: "\xA0Case sensitive",
|
|
1610
|
+
prevBtn: "← Prev",
|
|
1611
|
+
nextBtn: "Next →",
|
|
1612
|
+
replacePlaceholder: "Replace with…",
|
|
1613
|
+
replaceAriaLabel: "Replace with",
|
|
1614
|
+
replaceBtn: "Replace",
|
|
1615
|
+
replaceAllBtn: "Replace All",
|
|
1616
|
+
close: "×"
|
|
1617
|
+
},
|
|
1618
|
+
shortcutsDialog: {
|
|
1619
|
+
title: "Keyboard Shortcuts",
|
|
1620
|
+
ariaLabel: "Keyboard Shortcuts",
|
|
1621
|
+
close: "Close",
|
|
1622
|
+
shortcuts: [
|
|
1623
|
+
{
|
|
1624
|
+
category: "Text Formatting",
|
|
1625
|
+
items: [
|
|
1626
|
+
{
|
|
1627
|
+
keys: "Ctrl + B",
|
|
1628
|
+
action: "Bold"
|
|
1629
|
+
},
|
|
1630
|
+
{
|
|
1631
|
+
keys: "Ctrl + I",
|
|
1632
|
+
action: "Italic"
|
|
1633
|
+
},
|
|
1634
|
+
{
|
|
1635
|
+
keys: "Ctrl + U",
|
|
1636
|
+
action: "Underline"
|
|
1637
|
+
},
|
|
1638
|
+
{
|
|
1639
|
+
keys: "Ctrl + K",
|
|
1640
|
+
action: "Insert / edit link"
|
|
1641
|
+
}
|
|
1642
|
+
]
|
|
1643
|
+
},
|
|
1644
|
+
{
|
|
1645
|
+
category: "History",
|
|
1646
|
+
items: [{
|
|
1647
|
+
keys: "Ctrl + Z",
|
|
1648
|
+
action: "Undo"
|
|
1649
|
+
}, {
|
|
1650
|
+
keys: "Ctrl + Y / Ctrl + Shift + Z",
|
|
1651
|
+
action: "Redo"
|
|
1652
|
+
}]
|
|
1653
|
+
},
|
|
1654
|
+
{
|
|
1655
|
+
category: "Selection & Navigation",
|
|
1656
|
+
items: [
|
|
1657
|
+
{
|
|
1658
|
+
keys: "Ctrl + A",
|
|
1659
|
+
action: "Select all content"
|
|
1660
|
+
},
|
|
1661
|
+
{
|
|
1662
|
+
keys: "Tab",
|
|
1663
|
+
action: "Indent list item / insert spaces"
|
|
1664
|
+
},
|
|
1665
|
+
{
|
|
1666
|
+
keys: "Shift + Tab",
|
|
1667
|
+
action: "Outdent list item"
|
|
1668
|
+
}
|
|
1669
|
+
]
|
|
1670
|
+
},
|
|
1671
|
+
{
|
|
1672
|
+
category: "Clipboard",
|
|
1673
|
+
items: [{
|
|
1674
|
+
keys: "Ctrl + Shift + V",
|
|
1675
|
+
action: "Paste as plain text"
|
|
1676
|
+
}]
|
|
1677
|
+
},
|
|
1678
|
+
{
|
|
1679
|
+
category: "Find & Replace",
|
|
1680
|
+
items: [{
|
|
1681
|
+
keys: "Ctrl + F",
|
|
1682
|
+
action: "Find in document"
|
|
1683
|
+
}, {
|
|
1684
|
+
keys: "Ctrl + H",
|
|
1685
|
+
action: "Find & Replace"
|
|
1686
|
+
}]
|
|
1687
|
+
},
|
|
1688
|
+
{
|
|
1689
|
+
category: "Editor",
|
|
1690
|
+
items: [{
|
|
1691
|
+
keys: "Ctrl + Shift + /",
|
|
1692
|
+
action: "Show this keyboard shortcuts dialog"
|
|
1693
|
+
}]
|
|
1694
|
+
}
|
|
1695
|
+
]
|
|
1696
|
+
},
|
|
1697
|
+
contextMenu: {
|
|
1698
|
+
cut: "Cut",
|
|
1699
|
+
copy: "Copy",
|
|
1700
|
+
paste: "Paste",
|
|
1701
|
+
bold: "Bold",
|
|
1702
|
+
italic: "Italic",
|
|
1703
|
+
underline: "Underline",
|
|
1704
|
+
textColor: "Text Color",
|
|
1705
|
+
highlightColor: "Highlight Color",
|
|
1706
|
+
copyFormat: "Copy Format",
|
|
1707
|
+
pasteFormat: "Paste Format",
|
|
1708
|
+
removeFormat: "Remove Format",
|
|
1709
|
+
link: "Insert Link",
|
|
1710
|
+
image: "Insert Image",
|
|
1711
|
+
video: "Insert Video",
|
|
1712
|
+
table: "Insert Table",
|
|
1713
|
+
back: "Back",
|
|
1714
|
+
noHighlight: "No highlight",
|
|
1715
|
+
customColor: "Custom color",
|
|
1716
|
+
customColorLabel: "Custom…"
|
|
1717
|
+
},
|
|
1718
|
+
statusbar: {
|
|
1719
|
+
resizeHandle: "Resize editor",
|
|
1720
|
+
words: (n) => `Words: ${n}`,
|
|
1721
|
+
wordsLimit: (n, max) => `Words: ${n}/${max}`,
|
|
1722
|
+
chars: (n) => `Chars: ${n}`,
|
|
1723
|
+
charsLimit: (n, max) => `Chars: ${n}/${max}`
|
|
1724
|
+
},
|
|
1725
|
+
tooltips: {
|
|
1726
|
+
link: {
|
|
1727
|
+
ariaLabel: "Link actions",
|
|
1728
|
+
openLink: "Open link",
|
|
1729
|
+
copyUrl: "Copy URL",
|
|
1730
|
+
editLink: "Edit link",
|
|
1731
|
+
removeLink: "Remove link"
|
|
1732
|
+
},
|
|
1733
|
+
image: {
|
|
1734
|
+
ariaLabel: "Image actions",
|
|
1735
|
+
label: "Image",
|
|
1736
|
+
floatLeft: "Float Left",
|
|
1737
|
+
noFloat: "No Float",
|
|
1738
|
+
alignCenter: "Align Center",
|
|
1739
|
+
floatRight: "Float Right",
|
|
1740
|
+
originalSize: "Original Size",
|
|
1741
|
+
rotateLeft: "Rotate Left",
|
|
1742
|
+
rotateRight: "Rotate Right",
|
|
1743
|
+
cropImage: "Crop Image",
|
|
1744
|
+
addCaption: "Add / Edit Caption",
|
|
1745
|
+
deleteImage: "Delete Image"
|
|
1746
|
+
},
|
|
1747
|
+
code: {
|
|
1748
|
+
ariaLabel: "Code block actions",
|
|
1749
|
+
label: "Code",
|
|
1750
|
+
syntaxLanguage: "Syntax Language",
|
|
1751
|
+
syntaxAriaLabel: "Syntax language",
|
|
1752
|
+
copyCode: "Copy Code",
|
|
1753
|
+
toggleWordWrap: "Toggle Word Wrap",
|
|
1754
|
+
enableWordWrap: "Enable Word Wrap",
|
|
1755
|
+
disableWordWrap: "Disable Word Wrap",
|
|
1756
|
+
convertToParagraph: "Convert to Paragraph",
|
|
1757
|
+
deleteCodeBlock: "Delete Code Block"
|
|
1758
|
+
},
|
|
1759
|
+
table: {
|
|
1760
|
+
ariaLabel: "Table actions",
|
|
1761
|
+
label: "Table",
|
|
1762
|
+
selectCells: "Select Cells",
|
|
1763
|
+
addRowAbove: "Add Row Above",
|
|
1764
|
+
addRowBelow: "Add Row Below",
|
|
1765
|
+
deleteRow: "Delete Row",
|
|
1766
|
+
addColumnLeft: "Add Column Left",
|
|
1767
|
+
addColumnRight: "Add Column Right",
|
|
1768
|
+
deleteColumn: "Delete Column",
|
|
1769
|
+
mergeCells: "Merge Cells",
|
|
1770
|
+
unmergeCells: "Unmerge Cells",
|
|
1771
|
+
columnWidth: "Column Width",
|
|
1772
|
+
rowHeight: "Row Height",
|
|
1773
|
+
tableBorderWidth: "Table Border Width",
|
|
1774
|
+
deleteTable: "Delete Table",
|
|
1775
|
+
columnWidthPx: "Column Width (px)",
|
|
1776
|
+
rowHeightPx: "Row Height (px)",
|
|
1777
|
+
tableBorderWidthPx: "Table Border Width (px)",
|
|
1778
|
+
cancelBtn: "Cancel",
|
|
1779
|
+
applyBtn: "Apply"
|
|
1780
|
+
},
|
|
1781
|
+
video: {
|
|
1782
|
+
ariaLabel: "Video actions",
|
|
1783
|
+
label: "Video",
|
|
1784
|
+
floatLeft: "Float Left",
|
|
1785
|
+
noFloat: "No Float",
|
|
1786
|
+
alignCenter: "Align Center",
|
|
1787
|
+
floatRight: "Float Right",
|
|
1788
|
+
originalSize: "Original Size",
|
|
1789
|
+
previewVideo: "Preview Video",
|
|
1790
|
+
exitPreview: "Exit Preview",
|
|
1791
|
+
deleteVideo: "Delete Video"
|
|
1792
|
+
}
|
|
1793
|
+
},
|
|
1794
|
+
errors: {
|
|
1795
|
+
imageFormat: (type) => `Format "${type}" is not supported for display in web browsers. Please convert to JPEG, PNG, or WebP first.`,
|
|
1796
|
+
imageSize: (maxSize) => `Image file is too large. Maximum allowed size is ${maxSize} MB.`
|
|
1797
|
+
}
|
|
1798
|
+
};
|
|
1799
|
+
//#endregion
|
|
1800
|
+
//#region src/js/i18n/index.js
|
|
1801
|
+
/**
|
|
1802
|
+
* i18n/index.js — Locale registry and resolver for autumn-note-ce.
|
|
1803
|
+
*
|
|
1804
|
+
* Usage:
|
|
1805
|
+
* lang: 'en' → built-in English (default)
|
|
1806
|
+
* lang: 'vi' → built-in Vietnamese
|
|
1807
|
+
* lang: 'ja' → built-in Japanese
|
|
1808
|
+
* lang: 'zh' → built-in Simplified Chinese
|
|
1809
|
+
* lang: 'fr' → built-in French
|
|
1810
|
+
* lang: 'de' → built-in German
|
|
1811
|
+
* lang: 'es' → built-in Spanish
|
|
1812
|
+
* lang: 'ko' → built-in Korean
|
|
1813
|
+
* lang: { ... } → custom locale object, deep-merged over English
|
|
1814
|
+
*/
|
|
1815
|
+
/**
|
|
1816
|
+
* All built-in locales keyed by their language code.
|
|
1817
|
+
* @type {Record<string, Partial<AsnLocale>>}
|
|
1818
|
+
*/
|
|
1819
|
+
var locales = {
|
|
1820
|
+
en,
|
|
1821
|
+
vi: {
|
|
1822
|
+
toolbar: {
|
|
1823
|
+
bold: "Đậm (Ctrl+B)",
|
|
1824
|
+
italic: "Nghiêng (Ctrl+I)",
|
|
1825
|
+
underline: "Gạch chân (Ctrl+U)",
|
|
1826
|
+
strikethrough: "Gạch ngang",
|
|
1827
|
+
superscript: "Chỉ số trên",
|
|
1828
|
+
subscript: "Chỉ số dưới",
|
|
1829
|
+
alignLeft: "Căn trái",
|
|
1830
|
+
alignCenter: "Căn giữa",
|
|
1831
|
+
alignRight: "Căn phải",
|
|
1832
|
+
alignJustify: "Căn đều",
|
|
1833
|
+
ul: "Danh sách không thứ tự",
|
|
1834
|
+
ol: "Danh sách có thứ tự",
|
|
1835
|
+
checklist: "Danh sách kiểm tra",
|
|
1836
|
+
indent: "Tăng thụt đầu dòng",
|
|
1837
|
+
outdent: "Giảm thụt đầu dòng",
|
|
1838
|
+
undo: "Hoàn tác (Ctrl+Z)",
|
|
1839
|
+
redo: "Làm lại (Ctrl+Y)",
|
|
1840
|
+
hr: "Đường kẻ ngang",
|
|
1841
|
+
link: "Chèn liên kết",
|
|
1842
|
+
image: "Chèn hình ảnh",
|
|
1843
|
+
video: "Chèn video",
|
|
1844
|
+
emoji: "Chèn biểu tượng cảm xúc",
|
|
1845
|
+
icon: "Chèn biểu tượng FA",
|
|
1846
|
+
table: "Chèn bảng",
|
|
1847
|
+
fontSize: "Cỡ chữ",
|
|
1848
|
+
fontSizePlaceholder: "Cỡ",
|
|
1849
|
+
removeFormat: "Xóa định dạng",
|
|
1850
|
+
direction: "Chuyển hướng văn bản (LTR / RTL)",
|
|
1851
|
+
fontFamily: "Phông chữ",
|
|
1852
|
+
paragraphStyle: "Kiểu đoạn văn",
|
|
1853
|
+
paragraphStylePlaceholder: "Kiểu",
|
|
1854
|
+
lineHeight: "Khoảng cách dòng",
|
|
1855
|
+
lineHeightPlaceholder: "↕ Dòng",
|
|
1856
|
+
codeview: "Xem mã HTML",
|
|
1857
|
+
fullscreen: "Toàn màn hình",
|
|
1858
|
+
shortcuts: "Phím tắt (Ctrl+Shift+/)",
|
|
1859
|
+
find: "Tìm kiếm (Ctrl+F)",
|
|
1860
|
+
findReplace: "Tìm & Thay thế (Ctrl+H)",
|
|
1861
|
+
inlineCode: "Mã nội tuyến (Ctrl+`)",
|
|
1862
|
+
print: "In",
|
|
1863
|
+
foreColor: "Màu chữ",
|
|
1864
|
+
backColor: "Màu nền chữ",
|
|
1865
|
+
chooseTextColor: "Chọn màu chữ",
|
|
1866
|
+
chooseHighlightColor: "Chọn màu nền",
|
|
1867
|
+
customColor: "Màu tùy chỉnh",
|
|
1868
|
+
insertTableLabel: "Chèn bảng",
|
|
1869
|
+
paragraphItems: {
|
|
1870
|
+
p: "Bình thường",
|
|
1871
|
+
blockquote: "Trích dẫn",
|
|
1872
|
+
pre: "Mã"
|
|
1873
|
+
}
|
|
1874
|
+
},
|
|
1875
|
+
linkDialog: {
|
|
1876
|
+
ariaLabel: "Chèn liên kết",
|
|
1877
|
+
title: "Chèn liên kết",
|
|
1878
|
+
url: "Địa chỉ URL",
|
|
1879
|
+
urlPlaceholder: "https://",
|
|
1880
|
+
displayText: "Văn bản hiển thị",
|
|
1881
|
+
textPlaceholder: "Nội dung liên kết",
|
|
1882
|
+
openInNewTab: "Mở trong tab mới",
|
|
1883
|
+
insertBtn: "Chèn",
|
|
1884
|
+
cancelBtn: "Hủy"
|
|
1885
|
+
},
|
|
1886
|
+
imageDialog: {
|
|
1887
|
+
ariaLabel: "Chèn hình ảnh",
|
|
1888
|
+
title: "Chèn hình ảnh",
|
|
1889
|
+
imageUrl: "URL hình ảnh",
|
|
1890
|
+
urlPlaceholder: "https://example.com/anh.png",
|
|
1891
|
+
altText: "Văn bản thay thế",
|
|
1892
|
+
altPlaceholder: "Mô tả hình ảnh",
|
|
1893
|
+
alignment: "Căn chỉnh",
|
|
1894
|
+
alignNone: "Không",
|
|
1895
|
+
alignLeft: "Trái",
|
|
1896
|
+
alignCenter: "Giữa",
|
|
1897
|
+
alignRight: "Phải",
|
|
1898
|
+
uploadLabel: "Hoặc tải lên tệp",
|
|
1899
|
+
insertBtn: "Chèn",
|
|
1900
|
+
cancelBtn: "Hủy"
|
|
1901
|
+
},
|
|
1902
|
+
videoDialog: {
|
|
1903
|
+
ariaLabel: "Chèn video",
|
|
1904
|
+
title: "Chèn video",
|
|
1905
|
+
videoUrl: "URL video",
|
|
1906
|
+
urlPlaceholder: "YouTube, Vimeo, hoặc URL .mp4 trực tiếp",
|
|
1907
|
+
widthLabel: "Chiều rộng (px)",
|
|
1908
|
+
widthPlaceholder: "560",
|
|
1909
|
+
insertBtn: "Chèn",
|
|
1910
|
+
cancelBtn: "Hủy",
|
|
1911
|
+
detected: (type) => `Đã phát hiện: ${type}`,
|
|
1912
|
+
unknownFormat: "Định dạng không xác định — sẽ thử nhúng video trực tiếp",
|
|
1913
|
+
invalidUrl: "URL không hợp lệ — vui lòng nhập đường dẫn video hợp lệ."
|
|
1914
|
+
},
|
|
1915
|
+
emojiDialog: {
|
|
1916
|
+
ariaLabel: "Chèn biểu tượng cảm xúc",
|
|
1917
|
+
title: "Chèn biểu tượng cảm xúc",
|
|
1918
|
+
searchPlaceholder: "Tìm kiếm biểu tượng…",
|
|
1919
|
+
all: "Tất cả",
|
|
1920
|
+
cancelBtn: "Hủy",
|
|
1921
|
+
close: "Đóng",
|
|
1922
|
+
categories: {
|
|
1923
|
+
smileys: "Mặt cười",
|
|
1924
|
+
people: "Con người",
|
|
1925
|
+
animals: "Động vật",
|
|
1926
|
+
food: "Thức ăn",
|
|
1927
|
+
travel: "Du lịch",
|
|
1928
|
+
objects: "Đồ vật",
|
|
1929
|
+
symbols: "Ký hiệu"
|
|
1930
|
+
}
|
|
1931
|
+
},
|
|
1932
|
+
iconDialog: {
|
|
1933
|
+
ariaLabel: "Chèn biểu tượng FA",
|
|
1934
|
+
title: "Chèn biểu tượng FA",
|
|
1935
|
+
searchPlaceholder: "Tìm kiếm biểu tượng…",
|
|
1936
|
+
all: "Tất cả",
|
|
1937
|
+
style: "Kiểu",
|
|
1938
|
+
size: "Kích thước",
|
|
1939
|
+
color: "Màu sắc",
|
|
1940
|
+
useColor: " Dùng màu",
|
|
1941
|
+
selectHint: "Chọn một biểu tượng",
|
|
1942
|
+
insertBtn: "Chèn biểu tượng FA",
|
|
1943
|
+
cancelBtn: "Hủy",
|
|
1944
|
+
close: "Đóng",
|
|
1945
|
+
categories: {
|
|
1946
|
+
popular: "Phổ biến",
|
|
1947
|
+
interface: "Giao diện",
|
|
1948
|
+
navigation: "Điều hướng",
|
|
1949
|
+
media: "Phương tiện",
|
|
1950
|
+
communication: "Liên lạc",
|
|
1951
|
+
files: "Tệp tin",
|
|
1952
|
+
people: "Con người",
|
|
1953
|
+
objects: "Đồ vật"
|
|
1954
|
+
}
|
|
1955
|
+
},
|
|
1956
|
+
findReplace: {
|
|
1957
|
+
findTitle: "Tìm kiếm",
|
|
1958
|
+
findReplaceTitle: "Tìm & Thay thế",
|
|
1959
|
+
findPlaceholder: "Tìm…",
|
|
1960
|
+
searchAriaLabel: "Văn bản tìm kiếm",
|
|
1961
|
+
caseSensitive: "\xA0Phân biệt hoa thường",
|
|
1962
|
+
prevBtn: "← Trước",
|
|
1963
|
+
nextBtn: "Tiếp →",
|
|
1964
|
+
replacePlaceholder: "Thay thế bằng…",
|
|
1965
|
+
replaceAriaLabel: "Thay thế bằng",
|
|
1966
|
+
replaceBtn: "Thay thế",
|
|
1967
|
+
replaceAllBtn: "Thay thế tất cả",
|
|
1968
|
+
close: "×"
|
|
1969
|
+
},
|
|
1970
|
+
shortcutsDialog: {
|
|
1971
|
+
title: "Phím tắt bàn phím",
|
|
1972
|
+
ariaLabel: "Phím tắt bàn phím",
|
|
1973
|
+
close: "Đóng",
|
|
1974
|
+
shortcuts: [
|
|
1975
|
+
{
|
|
1976
|
+
category: "Định dạng văn bản",
|
|
1977
|
+
items: [
|
|
1978
|
+
{
|
|
1979
|
+
keys: "Ctrl + B",
|
|
1980
|
+
action: "Đậm"
|
|
1981
|
+
},
|
|
1982
|
+
{
|
|
1983
|
+
keys: "Ctrl + I",
|
|
1984
|
+
action: "Nghiêng"
|
|
1985
|
+
},
|
|
1986
|
+
{
|
|
1987
|
+
keys: "Ctrl + U",
|
|
1988
|
+
action: "Gạch chân"
|
|
1989
|
+
},
|
|
1990
|
+
{
|
|
1991
|
+
keys: "Ctrl + K",
|
|
1992
|
+
action: "Chèn / sửa liên kết"
|
|
1993
|
+
}
|
|
1994
|
+
]
|
|
1995
|
+
},
|
|
1996
|
+
{
|
|
1997
|
+
category: "Lịch sử",
|
|
1998
|
+
items: [{
|
|
1999
|
+
keys: "Ctrl + Z",
|
|
2000
|
+
action: "Hoàn tác"
|
|
2001
|
+
}, {
|
|
2002
|
+
keys: "Ctrl + Y / Ctrl + Shift + Z",
|
|
2003
|
+
action: "Làm lại"
|
|
2004
|
+
}]
|
|
2005
|
+
},
|
|
2006
|
+
{
|
|
2007
|
+
category: "Chọn & Điều hướng",
|
|
2008
|
+
items: [
|
|
2009
|
+
{
|
|
2010
|
+
keys: "Ctrl + A",
|
|
2011
|
+
action: "Chọn tất cả"
|
|
2012
|
+
},
|
|
2013
|
+
{
|
|
2014
|
+
keys: "Tab",
|
|
2015
|
+
action: "Tăng thụt đầu dòng / chèn khoảng trắng"
|
|
2016
|
+
},
|
|
2017
|
+
{
|
|
2018
|
+
keys: "Shift + Tab",
|
|
2019
|
+
action: "Giảm thụt đầu dòng"
|
|
2020
|
+
}
|
|
2021
|
+
]
|
|
2022
|
+
},
|
|
2023
|
+
{
|
|
2024
|
+
category: "Bảng nhớ tạm",
|
|
2025
|
+
items: [{
|
|
2026
|
+
keys: "Ctrl + Shift + V",
|
|
2027
|
+
action: "Dán dưới dạng văn bản thuần"
|
|
2028
|
+
}]
|
|
2029
|
+
},
|
|
2030
|
+
{
|
|
2031
|
+
category: "Tìm & Thay thế",
|
|
2032
|
+
items: [{
|
|
2033
|
+
keys: "Ctrl + F",
|
|
2034
|
+
action: "Tìm trong tài liệu"
|
|
2035
|
+
}, {
|
|
2036
|
+
keys: "Ctrl + H",
|
|
2037
|
+
action: "Tìm & Thay thế"
|
|
2038
|
+
}]
|
|
2039
|
+
},
|
|
2040
|
+
{
|
|
2041
|
+
category: "Trình soạn thảo",
|
|
2042
|
+
items: [{
|
|
2043
|
+
keys: "Ctrl + Shift + /",
|
|
2044
|
+
action: "Hiện hộp thoại phím tắt"
|
|
2045
|
+
}]
|
|
2046
|
+
}
|
|
2047
|
+
]
|
|
2048
|
+
},
|
|
2049
|
+
contextMenu: {
|
|
2050
|
+
cut: "Cắt",
|
|
2051
|
+
copy: "Sao chép",
|
|
2052
|
+
paste: "Dán",
|
|
2053
|
+
bold: "Đậm",
|
|
2054
|
+
italic: "Nghiêng",
|
|
2055
|
+
underline: "Gạch chân",
|
|
2056
|
+
textColor: "Màu chữ",
|
|
2057
|
+
highlightColor: "Màu nền chữ",
|
|
2058
|
+
copyFormat: "Sao chép định dạng",
|
|
2059
|
+
pasteFormat: "Dán định dạng",
|
|
2060
|
+
removeFormat: "Xóa định dạng",
|
|
2061
|
+
link: "Chèn liên kết",
|
|
2062
|
+
image: "Chèn hình ảnh",
|
|
2063
|
+
video: "Chèn video",
|
|
2064
|
+
table: "Chèn bảng",
|
|
2065
|
+
back: "Quay lại",
|
|
2066
|
+
noHighlight: "Không tô màu",
|
|
2067
|
+
customColor: "Màu tùy chỉnh",
|
|
2068
|
+
customColorLabel: "Tùy chỉnh…"
|
|
2069
|
+
},
|
|
2070
|
+
statusbar: {
|
|
2071
|
+
resizeHandle: "Kéo để thay đổi kích thước",
|
|
2072
|
+
words: (n) => `Từ: ${n}`,
|
|
2073
|
+
wordsLimit: (n, max) => `Từ: ${n}/${max}`,
|
|
2074
|
+
chars: (n) => `Ký tự: ${n}`,
|
|
2075
|
+
charsLimit: (n, max) => `Ký tự: ${n}/${max}`
|
|
2076
|
+
},
|
|
2077
|
+
tooltips: {
|
|
2078
|
+
link: {
|
|
2079
|
+
ariaLabel: "Hành động liên kết",
|
|
2080
|
+
openLink: "Mở liên kết",
|
|
2081
|
+
copyUrl: "Sao chép URL",
|
|
2082
|
+
editLink: "Sửa liên kết",
|
|
2083
|
+
removeLink: "Xóa liên kết"
|
|
2084
|
+
},
|
|
2085
|
+
image: {
|
|
2086
|
+
ariaLabel: "Hành động hình ảnh",
|
|
2087
|
+
label: "Hình ảnh",
|
|
2088
|
+
floatLeft: "Nổi trái",
|
|
2089
|
+
noFloat: "Không nổi",
|
|
2090
|
+
alignCenter: "Căn giữa",
|
|
2091
|
+
floatRight: "Nổi phải",
|
|
2092
|
+
originalSize: "Kích thước gốc",
|
|
2093
|
+
rotateLeft: "Xoay trái",
|
|
2094
|
+
rotateRight: "Xoay phải",
|
|
2095
|
+
cropImage: "Cắt ảnh",
|
|
2096
|
+
addCaption: "Thêm / Sửa chú thích",
|
|
2097
|
+
deleteImage: "Xóa hình ảnh"
|
|
2098
|
+
},
|
|
2099
|
+
code: {
|
|
2100
|
+
ariaLabel: "Hành động khối mã",
|
|
2101
|
+
label: "Mã",
|
|
2102
|
+
syntaxLanguage: "Ngôn ngữ cú pháp",
|
|
2103
|
+
syntaxAriaLabel: "Ngôn ngữ cú pháp",
|
|
2104
|
+
copyCode: "Sao chép mã",
|
|
2105
|
+
toggleWordWrap: "Chuyển đổi xuống dòng",
|
|
2106
|
+
enableWordWrap: "Bật xuống dòng",
|
|
2107
|
+
disableWordWrap: "Tắt xuống dòng",
|
|
2108
|
+
convertToParagraph: "Chuyển thành đoạn văn",
|
|
2109
|
+
deleteCodeBlock: "Xóa khối mã"
|
|
2110
|
+
},
|
|
2111
|
+
table: {
|
|
2112
|
+
ariaLabel: "Hành động bảng",
|
|
2113
|
+
label: "Bảng",
|
|
2114
|
+
selectCells: "Chọn ô",
|
|
2115
|
+
addRowAbove: "Thêm hàng phía trên",
|
|
2116
|
+
addRowBelow: "Thêm hàng phía dưới",
|
|
2117
|
+
deleteRow: "Xóa hàng",
|
|
2118
|
+
addColumnLeft: "Thêm cột bên trái",
|
|
2119
|
+
addColumnRight: "Thêm cột bên phải",
|
|
2120
|
+
deleteColumn: "Xóa cột",
|
|
2121
|
+
mergeCells: "Gộp ô",
|
|
2122
|
+
unmergeCells: "Tách ô",
|
|
2123
|
+
columnWidth: "Chiều rộng cột",
|
|
2124
|
+
rowHeight: "Chiều cao hàng",
|
|
2125
|
+
tableBorderWidth: "Độ rộng viền bảng",
|
|
2126
|
+
deleteTable: "Xóa bảng",
|
|
2127
|
+
columnWidthPx: "Chiều rộng cột (px)",
|
|
2128
|
+
rowHeightPx: "Chiều cao hàng (px)",
|
|
2129
|
+
tableBorderWidthPx: "Độ rộng viền bảng (px)",
|
|
2130
|
+
cancelBtn: "Hủy",
|
|
2131
|
+
applyBtn: "Áp dụng"
|
|
2132
|
+
},
|
|
2133
|
+
video: {
|
|
2134
|
+
ariaLabel: "Hành động video",
|
|
2135
|
+
label: "Video",
|
|
2136
|
+
floatLeft: "Nổi trái",
|
|
2137
|
+
noFloat: "Không nổi",
|
|
2138
|
+
alignCenter: "Căn giữa",
|
|
2139
|
+
floatRight: "Nổi phải",
|
|
2140
|
+
originalSize: "Kích thước gốc",
|
|
2141
|
+
previewVideo: "Xem trước",
|
|
2142
|
+
exitPreview: "Thoát xem trước",
|
|
2143
|
+
deleteVideo: "Xóa video"
|
|
2144
|
+
}
|
|
2145
|
+
},
|
|
2146
|
+
errors: {
|
|
2147
|
+
imageFormat: (type) => `Định dạng "${type}" không được hỗ trợ hiển thị trên trình duyệt. Vui lòng chuyển đổi sang JPEG, PNG hoặc WebP.`,
|
|
2148
|
+
imageSize: (maxSize) => `Tệp hình ảnh quá lớn. Kích thước tối đa cho phép là ${maxSize} MB.`
|
|
2149
|
+
}
|
|
2150
|
+
},
|
|
2151
|
+
ja: {
|
|
2152
|
+
toolbar: {
|
|
2153
|
+
bold: "太字 (Ctrl+B)",
|
|
2154
|
+
italic: "斜体 (Ctrl+I)",
|
|
2155
|
+
underline: "下線 (Ctrl+U)",
|
|
2156
|
+
strikethrough: "取り消し線",
|
|
2157
|
+
superscript: "上付き文字",
|
|
2158
|
+
subscript: "下付き文字",
|
|
2159
|
+
alignLeft: "左揃え",
|
|
2160
|
+
alignCenter: "中央揃え",
|
|
2161
|
+
alignRight: "右揃え",
|
|
2162
|
+
alignJustify: "両端揃え",
|
|
2163
|
+
ul: "箇条書きリスト",
|
|
2164
|
+
ol: "番号付きリスト",
|
|
2165
|
+
checklist: "チェックリスト",
|
|
2166
|
+
indent: "インデントを増やす",
|
|
2167
|
+
outdent: "インデントを減らす",
|
|
2168
|
+
undo: "元に戻す (Ctrl+Z)",
|
|
2169
|
+
redo: "やり直す (Ctrl+Y)",
|
|
2170
|
+
hr: "水平線",
|
|
2171
|
+
link: "リンクを挿入",
|
|
2172
|
+
image: "画像を挿入",
|
|
2173
|
+
video: "動画を挿入",
|
|
2174
|
+
emoji: "絵文字を挿入",
|
|
2175
|
+
icon: "FAアイコンを挿入",
|
|
2176
|
+
table: "テーブルを挿入",
|
|
2177
|
+
fontSize: "フォントサイズ",
|
|
2178
|
+
fontSizePlaceholder: "サイズ",
|
|
2179
|
+
removeFormat: "書式をリセット",
|
|
2180
|
+
direction: "文字方向を切り替え (LTR / RTL)",
|
|
2181
|
+
fontFamily: "フォント",
|
|
2182
|
+
paragraphStyle: "段落スタイル",
|
|
2183
|
+
paragraphStylePlaceholder: "スタイル",
|
|
2184
|
+
lineHeight: "行の高さ",
|
|
2185
|
+
lineHeightPlaceholder: "↕ 行間",
|
|
2186
|
+
codeview: "HTMLソースを表示",
|
|
2187
|
+
fullscreen: "全画面表示",
|
|
2188
|
+
shortcuts: "キーボードショートカット (Ctrl+Shift+/)",
|
|
2189
|
+
find: "検索 (Ctrl+F)",
|
|
2190
|
+
findReplace: "検索と置換 (Ctrl+H)",
|
|
2191
|
+
inlineCode: "インラインコード (Ctrl+`)",
|
|
2192
|
+
print: "印刷",
|
|
2193
|
+
foreColor: "文字色",
|
|
2194
|
+
backColor: "ハイライト色",
|
|
2195
|
+
chooseTextColor: "文字色を選択",
|
|
2196
|
+
chooseHighlightColor: "ハイライト色を選択",
|
|
2197
|
+
customColor: "カスタムカラー",
|
|
2198
|
+
insertTableLabel: "テーブルを挿入",
|
|
2199
|
+
paragraphItems: {
|
|
2200
|
+
p: "標準",
|
|
2201
|
+
blockquote: "引用",
|
|
2202
|
+
pre: "コード"
|
|
2203
|
+
}
|
|
2204
|
+
},
|
|
2205
|
+
linkDialog: {
|
|
2206
|
+
ariaLabel: "リンクを挿入",
|
|
2207
|
+
title: "リンクを挿入",
|
|
2208
|
+
url: "URL",
|
|
2209
|
+
urlPlaceholder: "https://",
|
|
2210
|
+
displayText: "表示テキスト",
|
|
2211
|
+
textPlaceholder: "リンクテキスト",
|
|
2212
|
+
openInNewTab: "新しいタブで開く",
|
|
2213
|
+
insertBtn: "挿入",
|
|
2214
|
+
cancelBtn: "キャンセル"
|
|
2215
|
+
},
|
|
2216
|
+
imageDialog: {
|
|
2217
|
+
ariaLabel: "画像を挿入",
|
|
2218
|
+
title: "画像を挿入",
|
|
2219
|
+
imageUrl: "画像URL",
|
|
2220
|
+
urlPlaceholder: "https://example.com/image.png",
|
|
2221
|
+
altText: "代替テキスト",
|
|
2222
|
+
altPlaceholder: "画像の説明",
|
|
2223
|
+
alignment: "配置",
|
|
2224
|
+
alignNone: "なし",
|
|
2225
|
+
alignLeft: "左",
|
|
2226
|
+
alignCenter: "中央",
|
|
2227
|
+
alignRight: "右",
|
|
2228
|
+
uploadLabel: "ファイルをアップロード",
|
|
2229
|
+
insertBtn: "挿入",
|
|
2230
|
+
cancelBtn: "キャンセル"
|
|
2231
|
+
},
|
|
2232
|
+
videoDialog: {
|
|
2233
|
+
ariaLabel: "動画を挿入",
|
|
2234
|
+
title: "動画を挿入",
|
|
2235
|
+
videoUrl: "動画URL",
|
|
2236
|
+
urlPlaceholder: "YouTube、Vimeo、または直接動画URL",
|
|
2237
|
+
widthLabel: "幅 (px)",
|
|
2238
|
+
widthPlaceholder: "560",
|
|
2239
|
+
insertBtn: "挿入",
|
|
2240
|
+
cancelBtn: "キャンセル",
|
|
2241
|
+
detected: (type) => `検出: ${type}`,
|
|
2242
|
+
unknownFormat: "不明な形式 — 直接動画埋め込みを試みます",
|
|
2243
|
+
invalidUrl: "URLが無効です — 有効な動画URLを入力してください。"
|
|
2244
|
+
},
|
|
2245
|
+
emojiDialog: {
|
|
2246
|
+
ariaLabel: "絵文字を挿入",
|
|
2247
|
+
title: "絵文字を挿入",
|
|
2248
|
+
searchPlaceholder: "絵文字を検索…",
|
|
2249
|
+
all: "すべて",
|
|
2250
|
+
cancelBtn: "キャンセル",
|
|
2251
|
+
close: "閉じる",
|
|
2252
|
+
categories: {
|
|
2253
|
+
smileys: "顔文字",
|
|
2254
|
+
people: "人物",
|
|
2255
|
+
animals: "動物",
|
|
2256
|
+
food: "食べ物",
|
|
2257
|
+
travel: "旅行",
|
|
2258
|
+
objects: "モノ",
|
|
2259
|
+
symbols: "記号"
|
|
2260
|
+
}
|
|
2261
|
+
},
|
|
2262
|
+
iconDialog: {
|
|
2263
|
+
ariaLabel: "FAアイコンを挿入",
|
|
2264
|
+
title: "FAアイコンを挿入",
|
|
2265
|
+
searchPlaceholder: "アイコンを検索…",
|
|
2266
|
+
all: "すべて",
|
|
2267
|
+
style: "スタイル",
|
|
2268
|
+
size: "サイズ",
|
|
2269
|
+
color: "カラー",
|
|
2270
|
+
useColor: " カラーを使用",
|
|
2271
|
+
selectHint: "アイコンを選択してください",
|
|
2272
|
+
insertBtn: "FAアイコンを挿入",
|
|
2273
|
+
cancelBtn: "キャンセル",
|
|
2274
|
+
close: "閉じる",
|
|
2275
|
+
categories: {
|
|
2276
|
+
popular: "人気",
|
|
2277
|
+
interface: "インターフェース",
|
|
2278
|
+
navigation: "ナビゲーション",
|
|
2279
|
+
media: "メディア",
|
|
2280
|
+
communication: "通信",
|
|
2281
|
+
files: "ファイル",
|
|
2282
|
+
people: "人物",
|
|
2283
|
+
objects: "モノ"
|
|
2284
|
+
}
|
|
2285
|
+
},
|
|
2286
|
+
findReplace: {
|
|
2287
|
+
findTitle: "検索",
|
|
2288
|
+
findReplaceTitle: "検索と置換",
|
|
2289
|
+
findPlaceholder: "検索…",
|
|
2290
|
+
searchAriaLabel: "検索テキスト",
|
|
2291
|
+
caseSensitive: "\xA0大文字/小文字を区別",
|
|
2292
|
+
prevBtn: "← 前へ",
|
|
2293
|
+
nextBtn: "次へ →",
|
|
2294
|
+
replacePlaceholder: "置換後…",
|
|
2295
|
+
replaceAriaLabel: "置換後のテキスト",
|
|
2296
|
+
replaceBtn: "置換",
|
|
2297
|
+
replaceAllBtn: "すべて置換",
|
|
2298
|
+
close: "×"
|
|
2299
|
+
},
|
|
2300
|
+
shortcutsDialog: {
|
|
2301
|
+
title: "キーボードショートカット",
|
|
2302
|
+
ariaLabel: "キーボードショートカット",
|
|
2303
|
+
close: "閉じる",
|
|
2304
|
+
shortcuts: [
|
|
2305
|
+
{
|
|
2306
|
+
category: "テキスト書式",
|
|
2307
|
+
items: [
|
|
2308
|
+
{
|
|
2309
|
+
keys: "Ctrl + B",
|
|
2310
|
+
action: "太字"
|
|
2311
|
+
},
|
|
2312
|
+
{
|
|
2313
|
+
keys: "Ctrl + I",
|
|
2314
|
+
action: "斜体"
|
|
2315
|
+
},
|
|
2316
|
+
{
|
|
2317
|
+
keys: "Ctrl + U",
|
|
2318
|
+
action: "下線"
|
|
2319
|
+
},
|
|
2320
|
+
{
|
|
2321
|
+
keys: "Ctrl + K",
|
|
2322
|
+
action: "リンクの挿入 / 編集"
|
|
2323
|
+
}
|
|
2324
|
+
]
|
|
2325
|
+
},
|
|
2326
|
+
{
|
|
2327
|
+
category: "履歴",
|
|
2328
|
+
items: [{
|
|
2329
|
+
keys: "Ctrl + Z",
|
|
2330
|
+
action: "元に戻す"
|
|
2331
|
+
}, {
|
|
2332
|
+
keys: "Ctrl + Y / Ctrl + Shift + Z",
|
|
2333
|
+
action: "やり直す"
|
|
2334
|
+
}]
|
|
2335
|
+
},
|
|
2336
|
+
{
|
|
2337
|
+
category: "選択と移動",
|
|
2338
|
+
items: [
|
|
2339
|
+
{
|
|
2340
|
+
keys: "Ctrl + A",
|
|
2341
|
+
action: "すべて選択"
|
|
2342
|
+
},
|
|
2343
|
+
{
|
|
2344
|
+
keys: "Tab",
|
|
2345
|
+
action: "インデント増加 / スペース挿入"
|
|
2346
|
+
},
|
|
2347
|
+
{
|
|
2348
|
+
keys: "Shift + Tab",
|
|
2349
|
+
action: "インデント減少"
|
|
2350
|
+
}
|
|
2351
|
+
]
|
|
2352
|
+
},
|
|
2353
|
+
{
|
|
2354
|
+
category: "クリップボード",
|
|
2355
|
+
items: [{
|
|
2356
|
+
keys: "Ctrl + Shift + V",
|
|
2357
|
+
action: "プレーンテキストとして貼り付け"
|
|
2358
|
+
}]
|
|
2359
|
+
},
|
|
2360
|
+
{
|
|
2361
|
+
category: "検索と置換",
|
|
2362
|
+
items: [{
|
|
2363
|
+
keys: "Ctrl + F",
|
|
2364
|
+
action: "文書内を検索"
|
|
2365
|
+
}, {
|
|
2366
|
+
keys: "Ctrl + H",
|
|
2367
|
+
action: "検索と置換"
|
|
2368
|
+
}]
|
|
2369
|
+
},
|
|
2370
|
+
{
|
|
2371
|
+
category: "エディター",
|
|
2372
|
+
items: [{
|
|
2373
|
+
keys: "Ctrl + Shift + /",
|
|
2374
|
+
action: "ショートカットダイアログを表示"
|
|
2375
|
+
}]
|
|
2376
|
+
}
|
|
2377
|
+
]
|
|
2378
|
+
},
|
|
2379
|
+
contextMenu: {
|
|
2380
|
+
cut: "切り取り",
|
|
2381
|
+
copy: "コピー",
|
|
2382
|
+
paste: "貼り付け",
|
|
2383
|
+
bold: "太字",
|
|
2384
|
+
italic: "斜体",
|
|
2385
|
+
underline: "下線",
|
|
2386
|
+
textColor: "文字色",
|
|
2387
|
+
highlightColor: "ハイライト色",
|
|
2388
|
+
copyFormat: "書式をコピー",
|
|
2389
|
+
pasteFormat: "書式を貼り付け",
|
|
2390
|
+
removeFormat: "書式をリセット",
|
|
2391
|
+
link: "リンクを挿入",
|
|
2392
|
+
image: "画像を挿入",
|
|
2393
|
+
video: "動画を挿入",
|
|
2394
|
+
table: "テーブルを挿入",
|
|
2395
|
+
back: "戻る",
|
|
2396
|
+
noHighlight: "ハイライトなし",
|
|
2397
|
+
customColor: "カスタムカラー",
|
|
2398
|
+
customColorLabel: "カスタム…"
|
|
2399
|
+
},
|
|
2400
|
+
statusbar: {
|
|
2401
|
+
resizeHandle: "ドラッグしてリサイズ",
|
|
2402
|
+
words: (n) => `単語数: ${n}`,
|
|
2403
|
+
wordsLimit: (n, max) => `単語数: ${n}/${max}`,
|
|
2404
|
+
chars: (n) => `文字数: ${n}`,
|
|
2405
|
+
charsLimit: (n, max) => `文字数: ${n}/${max}`
|
|
2406
|
+
},
|
|
2407
|
+
tooltips: {
|
|
2408
|
+
link: {
|
|
2409
|
+
ariaLabel: "リンク操作",
|
|
2410
|
+
openLink: "リンクを開く",
|
|
2411
|
+
copyUrl: "URLをコピー",
|
|
2412
|
+
editLink: "リンクを編集",
|
|
2413
|
+
removeLink: "リンクを削除"
|
|
2414
|
+
},
|
|
2415
|
+
image: {
|
|
2416
|
+
ariaLabel: "画像操作",
|
|
2417
|
+
label: "画像",
|
|
2418
|
+
floatLeft: "左に回り込み",
|
|
2419
|
+
noFloat: "回り込みなし",
|
|
2420
|
+
alignCenter: "中央揃え",
|
|
2421
|
+
floatRight: "右に回り込み",
|
|
2422
|
+
originalSize: "元のサイズ",
|
|
2423
|
+
rotateLeft: "左に回転",
|
|
2424
|
+
rotateRight: "右に回転",
|
|
2425
|
+
cropImage: "画像をトリミング",
|
|
2426
|
+
addCaption: "キャプションを追加 / 編集",
|
|
2427
|
+
deleteImage: "画像を削除"
|
|
2428
|
+
},
|
|
2429
|
+
code: {
|
|
2430
|
+
ariaLabel: "コードブロック操作",
|
|
2431
|
+
label: "コード",
|
|
2432
|
+
syntaxLanguage: "言語",
|
|
2433
|
+
syntaxAriaLabel: "構文言語",
|
|
2434
|
+
copyCode: "コードをコピー",
|
|
2435
|
+
toggleWordWrap: "折り返しを切り替え",
|
|
2436
|
+
enableWordWrap: "折り返しを有効にする",
|
|
2437
|
+
disableWordWrap: "折り返しを無効にする",
|
|
2438
|
+
convertToParagraph: "段落に変換",
|
|
2439
|
+
deleteCodeBlock: "コードブロックを削除"
|
|
2440
|
+
},
|
|
2441
|
+
table: {
|
|
2442
|
+
ariaLabel: "テーブル操作",
|
|
2443
|
+
label: "テーブル",
|
|
2444
|
+
selectCells: "セルを選択",
|
|
2445
|
+
addRowAbove: "上に行を追加",
|
|
2446
|
+
addRowBelow: "下に行を追加",
|
|
2447
|
+
deleteRow: "行を削除",
|
|
2448
|
+
addColumnLeft: "左に列を追加",
|
|
2449
|
+
addColumnRight: "右に列を追加",
|
|
2450
|
+
deleteColumn: "列を削除",
|
|
2451
|
+
mergeCells: "セルを結合",
|
|
2452
|
+
unmergeCells: "セルの結合を解除",
|
|
2453
|
+
columnWidth: "列幅",
|
|
2454
|
+
rowHeight: "行の高さ",
|
|
2455
|
+
tableBorderWidth: "テーブルの枠幅",
|
|
2456
|
+
deleteTable: "テーブルを削除",
|
|
2457
|
+
columnWidthPx: "列幅 (px)",
|
|
2458
|
+
rowHeightPx: "行の高さ (px)",
|
|
2459
|
+
tableBorderWidthPx: "テーブルの枠幅 (px)",
|
|
2460
|
+
cancelBtn: "キャンセル",
|
|
2461
|
+
applyBtn: "適用"
|
|
2462
|
+
},
|
|
2463
|
+
video: {
|
|
2464
|
+
ariaLabel: "動画操作",
|
|
2465
|
+
label: "動画",
|
|
2466
|
+
floatLeft: "左に回り込み",
|
|
2467
|
+
noFloat: "回り込みなし",
|
|
2468
|
+
alignCenter: "中央揃え",
|
|
2469
|
+
floatRight: "右に回り込み",
|
|
2470
|
+
originalSize: "元のサイズ",
|
|
2471
|
+
previewVideo: "プレビュー",
|
|
2472
|
+
exitPreview: "プレビューを終了",
|
|
2473
|
+
deleteVideo: "動画を削除"
|
|
2474
|
+
}
|
|
2475
|
+
},
|
|
2476
|
+
errors: {
|
|
2477
|
+
imageFormat: (type) => `形式 "${type}" はブラウザでの表示をサポートしていません。JPEG、PNG、または WebP に変換してください。`,
|
|
2478
|
+
imageSize: (maxSize) => `画像ファイルが大きすぎます。最大許容サイズは ${maxSize} MB です。`
|
|
2479
|
+
}
|
|
2480
|
+
},
|
|
2481
|
+
zh: {
|
|
2482
|
+
toolbar: {
|
|
2483
|
+
bold: "粗体 (Ctrl+B)",
|
|
2484
|
+
italic: "斜体 (Ctrl+I)",
|
|
2485
|
+
underline: "下划线 (Ctrl+U)",
|
|
2486
|
+
strikethrough: "删除线",
|
|
2487
|
+
superscript: "上标",
|
|
2488
|
+
subscript: "下标",
|
|
2489
|
+
alignLeft: "左对齐",
|
|
2490
|
+
alignCenter: "居中",
|
|
2491
|
+
alignRight: "右对齐",
|
|
2492
|
+
alignJustify: "两端对齐",
|
|
2493
|
+
ul: "无序列表",
|
|
2494
|
+
ol: "有序列表",
|
|
2495
|
+
checklist: "待办列表",
|
|
2496
|
+
indent: "增加缩进",
|
|
2497
|
+
outdent: "减少缩进",
|
|
2498
|
+
undo: "撤销 (Ctrl+Z)",
|
|
2499
|
+
redo: "重做 (Ctrl+Y)",
|
|
2500
|
+
hr: "水平分割线",
|
|
2501
|
+
link: "插入链接",
|
|
2502
|
+
image: "插入图片",
|
|
2503
|
+
video: "插入视频",
|
|
2504
|
+
emoji: "插入表情",
|
|
2505
|
+
icon: "插入 FA 图标",
|
|
2506
|
+
table: "插入表格",
|
|
2507
|
+
fontSize: "字号",
|
|
2508
|
+
fontSizePlaceholder: "大小",
|
|
2509
|
+
removeFormat: "清除格式",
|
|
2510
|
+
direction: "切换文字方向 (LTR / RTL)",
|
|
2511
|
+
fontFamily: "字体",
|
|
2512
|
+
paragraphStyle: "段落样式",
|
|
2513
|
+
paragraphStylePlaceholder: "样式",
|
|
2514
|
+
lineHeight: "行高",
|
|
2515
|
+
lineHeightPlaceholder: "↕ 行距",
|
|
2516
|
+
codeview: "查看 HTML 源码",
|
|
2517
|
+
fullscreen: "全屏",
|
|
2518
|
+
shortcuts: "键盘快捷键 (Ctrl+Shift+/)",
|
|
2519
|
+
find: "搜索 (Ctrl+F)",
|
|
2520
|
+
findReplace: "查找和替换 (Ctrl+H)",
|
|
2521
|
+
inlineCode: "行内代码 (Ctrl+`)",
|
|
2522
|
+
print: "打印",
|
|
2523
|
+
foreColor: "文字颜色",
|
|
2524
|
+
backColor: "高亮颜色",
|
|
2525
|
+
chooseTextColor: "选择文字颜色",
|
|
2526
|
+
chooseHighlightColor: "选择高亮颜色",
|
|
2527
|
+
customColor: "自定义颜色",
|
|
2528
|
+
insertTableLabel: "插入表格",
|
|
2529
|
+
paragraphItems: {
|
|
2530
|
+
p: "正文",
|
|
2531
|
+
blockquote: "引用",
|
|
2532
|
+
pre: "代码"
|
|
2533
|
+
}
|
|
2534
|
+
},
|
|
2535
|
+
linkDialog: {
|
|
2536
|
+
ariaLabel: "插入链接",
|
|
2537
|
+
title: "插入链接",
|
|
2538
|
+
url: "链接地址",
|
|
2539
|
+
urlPlaceholder: "https://",
|
|
2540
|
+
displayText: "显示文字",
|
|
2541
|
+
textPlaceholder: "链接文字",
|
|
2542
|
+
openInNewTab: "在新标签页中打开",
|
|
2543
|
+
insertBtn: "插入",
|
|
2544
|
+
cancelBtn: "取消"
|
|
2545
|
+
},
|
|
2546
|
+
imageDialog: {
|
|
2547
|
+
ariaLabel: "插入图片",
|
|
2548
|
+
title: "插入图片",
|
|
2549
|
+
imageUrl: "图片地址",
|
|
2550
|
+
urlPlaceholder: "https://example.com/image.png",
|
|
2551
|
+
altText: "替代文字",
|
|
2552
|
+
altPlaceholder: "图片描述",
|
|
2553
|
+
alignment: "对齐方式",
|
|
2554
|
+
alignNone: "无",
|
|
2555
|
+
alignLeft: "左",
|
|
2556
|
+
alignCenter: "居中",
|
|
2557
|
+
alignRight: "右",
|
|
2558
|
+
uploadLabel: "或上传文件",
|
|
2559
|
+
insertBtn: "插入",
|
|
2560
|
+
cancelBtn: "取消"
|
|
2561
|
+
},
|
|
2562
|
+
videoDialog: {
|
|
2563
|
+
ariaLabel: "插入视频",
|
|
2564
|
+
title: "插入视频",
|
|
2565
|
+
videoUrl: "视频地址",
|
|
2566
|
+
urlPlaceholder: "YouTube、Vimeo 或直接 .mp4 链接",
|
|
2567
|
+
widthLabel: "宽度 (px)",
|
|
2568
|
+
widthPlaceholder: "560",
|
|
2569
|
+
insertBtn: "插入",
|
|
2570
|
+
cancelBtn: "取消",
|
|
2571
|
+
detected: (type) => `已识别: ${type}`,
|
|
2572
|
+
unknownFormat: "未知格式 — 将尝试直接嵌入视频",
|
|
2573
|
+
invalidUrl: "URL 无效 — 请输入有效的视频链接。"
|
|
2574
|
+
},
|
|
2575
|
+
emojiDialog: {
|
|
2576
|
+
ariaLabel: "插入表情",
|
|
2577
|
+
title: "插入表情",
|
|
2578
|
+
searchPlaceholder: "搜索表情…",
|
|
2579
|
+
all: "全部",
|
|
2580
|
+
cancelBtn: "取消",
|
|
2581
|
+
close: "关闭",
|
|
2582
|
+
categories: {
|
|
2583
|
+
smileys: "笑脸",
|
|
2584
|
+
people: "人物",
|
|
2585
|
+
animals: "动物",
|
|
2586
|
+
food: "食物",
|
|
2587
|
+
travel: "旅行",
|
|
2588
|
+
objects: "物品",
|
|
2589
|
+
symbols: "符号"
|
|
2590
|
+
}
|
|
2591
|
+
},
|
|
2592
|
+
iconDialog: {
|
|
2593
|
+
ariaLabel: "插入 FA 图标",
|
|
2594
|
+
title: "插入 FA 图标",
|
|
2595
|
+
searchPlaceholder: "搜索图标…",
|
|
2596
|
+
all: "全部",
|
|
2597
|
+
style: "样式",
|
|
2598
|
+
size: "大小",
|
|
2599
|
+
color: "颜色",
|
|
2600
|
+
useColor: " 使用颜色",
|
|
2601
|
+
selectHint: "请选择一个图标",
|
|
2602
|
+
insertBtn: "插入 FA 图标",
|
|
2603
|
+
cancelBtn: "取消",
|
|
2604
|
+
close: "关闭",
|
|
2605
|
+
categories: {
|
|
2606
|
+
popular: "热门",
|
|
2607
|
+
interface: "界面",
|
|
2608
|
+
navigation: "导航",
|
|
2609
|
+
media: "媒体",
|
|
2610
|
+
communication: "通讯",
|
|
2611
|
+
files: "文件",
|
|
2612
|
+
people: "人物",
|
|
2613
|
+
objects: "物品"
|
|
2614
|
+
}
|
|
2615
|
+
},
|
|
2616
|
+
findReplace: {
|
|
2617
|
+
findTitle: "搜索",
|
|
2618
|
+
findReplaceTitle: "查找和替换",
|
|
2619
|
+
findPlaceholder: "查找…",
|
|
2620
|
+
searchAriaLabel: "搜索文字",
|
|
2621
|
+
caseSensitive: "\xA0区分大小写",
|
|
2622
|
+
prevBtn: "← 上一个",
|
|
2623
|
+
nextBtn: "下一个 →",
|
|
2624
|
+
replacePlaceholder: "替换为…",
|
|
2625
|
+
replaceAriaLabel: "替换为",
|
|
2626
|
+
replaceBtn: "替换",
|
|
2627
|
+
replaceAllBtn: "全部替换",
|
|
2628
|
+
close: "×"
|
|
2629
|
+
},
|
|
2630
|
+
shortcutsDialog: {
|
|
2631
|
+
title: "键盘快捷键",
|
|
2632
|
+
ariaLabel: "键盘快捷键",
|
|
2633
|
+
close: "关闭",
|
|
2634
|
+
shortcuts: [
|
|
2635
|
+
{
|
|
2636
|
+
category: "文字格式",
|
|
2637
|
+
items: [
|
|
2638
|
+
{
|
|
2639
|
+
keys: "Ctrl + B",
|
|
2640
|
+
action: "粗体"
|
|
2641
|
+
},
|
|
2642
|
+
{
|
|
2643
|
+
keys: "Ctrl + I",
|
|
2644
|
+
action: "斜体"
|
|
2645
|
+
},
|
|
2646
|
+
{
|
|
2647
|
+
keys: "Ctrl + U",
|
|
2648
|
+
action: "下划线"
|
|
2649
|
+
},
|
|
2650
|
+
{
|
|
2651
|
+
keys: "Ctrl + K",
|
|
2652
|
+
action: "插入 / 编辑链接"
|
|
2653
|
+
}
|
|
2654
|
+
]
|
|
2655
|
+
},
|
|
2656
|
+
{
|
|
2657
|
+
category: "历史记录",
|
|
2658
|
+
items: [{
|
|
2659
|
+
keys: "Ctrl + Z",
|
|
2660
|
+
action: "撤销"
|
|
2661
|
+
}, {
|
|
2662
|
+
keys: "Ctrl + Y / Ctrl + Shift + Z",
|
|
2663
|
+
action: "重做"
|
|
2664
|
+
}]
|
|
2665
|
+
},
|
|
2666
|
+
{
|
|
2667
|
+
category: "选择与导航",
|
|
2668
|
+
items: [
|
|
2669
|
+
{
|
|
2670
|
+
keys: "Ctrl + A",
|
|
2671
|
+
action: "全选"
|
|
2672
|
+
},
|
|
2673
|
+
{
|
|
2674
|
+
keys: "Tab",
|
|
2675
|
+
action: "增加缩进 / 插入空格"
|
|
2676
|
+
},
|
|
2677
|
+
{
|
|
2678
|
+
keys: "Shift + Tab",
|
|
2679
|
+
action: "减少缩进"
|
|
2680
|
+
}
|
|
2681
|
+
]
|
|
2682
|
+
},
|
|
2683
|
+
{
|
|
2684
|
+
category: "剪贴板",
|
|
2685
|
+
items: [{
|
|
2686
|
+
keys: "Ctrl + Shift + V",
|
|
2687
|
+
action: "粘贴为纯文本"
|
|
2688
|
+
}]
|
|
2689
|
+
},
|
|
2690
|
+
{
|
|
2691
|
+
category: "查找和替换",
|
|
2692
|
+
items: [{
|
|
2693
|
+
keys: "Ctrl + F",
|
|
2694
|
+
action: "在文档中搜索"
|
|
2695
|
+
}, {
|
|
2696
|
+
keys: "Ctrl + H",
|
|
2697
|
+
action: "查找和替换"
|
|
2698
|
+
}]
|
|
2699
|
+
},
|
|
2700
|
+
{
|
|
2701
|
+
category: "编辑器",
|
|
2702
|
+
items: [{
|
|
2703
|
+
keys: "Ctrl + Shift + /",
|
|
2704
|
+
action: "显示快捷键对话框"
|
|
2705
|
+
}]
|
|
2706
|
+
}
|
|
2707
|
+
]
|
|
2708
|
+
},
|
|
2709
|
+
contextMenu: {
|
|
2710
|
+
cut: "剪切",
|
|
2711
|
+
copy: "复制",
|
|
2712
|
+
paste: "粘贴",
|
|
2713
|
+
bold: "粗体",
|
|
2714
|
+
italic: "斜体",
|
|
2715
|
+
underline: "下划线",
|
|
2716
|
+
textColor: "文字颜色",
|
|
2717
|
+
highlightColor: "高亮颜色",
|
|
2718
|
+
copyFormat: "复制格式",
|
|
2719
|
+
pasteFormat: "粘贴格式",
|
|
2720
|
+
removeFormat: "清除格式",
|
|
2721
|
+
link: "插入链接",
|
|
2722
|
+
image: "插入图片",
|
|
2723
|
+
video: "插入视频",
|
|
2724
|
+
table: "插入表格",
|
|
2725
|
+
back: "返回",
|
|
2726
|
+
noHighlight: "无高亮",
|
|
2727
|
+
customColor: "自定义颜色",
|
|
2728
|
+
customColorLabel: "自定义…"
|
|
2729
|
+
},
|
|
2730
|
+
statusbar: {
|
|
2731
|
+
resizeHandle: "拖动以调整大小",
|
|
2732
|
+
words: (n) => `字数: ${n}`,
|
|
2733
|
+
wordsLimit: (n, max) => `字数: ${n}/${max}`,
|
|
2734
|
+
chars: (n) => `字符数: ${n}`,
|
|
2735
|
+
charsLimit: (n, max) => `字符数: ${n}/${max}`
|
|
2736
|
+
},
|
|
2737
|
+
tooltips: {
|
|
2738
|
+
link: {
|
|
2739
|
+
ariaLabel: "链接操作",
|
|
2740
|
+
openLink: "打开链接",
|
|
2741
|
+
copyUrl: "复制 URL",
|
|
2742
|
+
editLink: "编辑链接",
|
|
2743
|
+
removeLink: "删除链接"
|
|
2744
|
+
},
|
|
2745
|
+
image: {
|
|
2746
|
+
ariaLabel: "图片操作",
|
|
2747
|
+
label: "图片",
|
|
2748
|
+
floatLeft: "左浮动",
|
|
2749
|
+
noFloat: "不浮动",
|
|
2750
|
+
alignCenter: "居中对齐",
|
|
2751
|
+
floatRight: "右浮动",
|
|
2752
|
+
originalSize: "原始尺寸",
|
|
2753
|
+
rotateLeft: "向左旋转",
|
|
2754
|
+
rotateRight: "向右旋转",
|
|
2755
|
+
cropImage: "裁剪图片",
|
|
2756
|
+
addCaption: "添加 / 编辑说明",
|
|
2757
|
+
deleteImage: "删除图片"
|
|
2758
|
+
},
|
|
2759
|
+
code: {
|
|
2760
|
+
ariaLabel: "代码块操作",
|
|
2761
|
+
label: "代码",
|
|
2762
|
+
syntaxLanguage: "语法语言",
|
|
2763
|
+
syntaxAriaLabel: "语法语言",
|
|
2764
|
+
copyCode: "复制代码",
|
|
2765
|
+
toggleWordWrap: "切换自动换行",
|
|
2766
|
+
enableWordWrap: "启用自动换行",
|
|
2767
|
+
disableWordWrap: "禁用自动换行",
|
|
2768
|
+
convertToParagraph: "转换为段落",
|
|
2769
|
+
deleteCodeBlock: "删除代码块"
|
|
2770
|
+
},
|
|
2771
|
+
table: {
|
|
2772
|
+
ariaLabel: "表格操作",
|
|
2773
|
+
label: "表格",
|
|
2774
|
+
selectCells: "选择单元格",
|
|
2775
|
+
addRowAbove: "在上方插入行",
|
|
2776
|
+
addRowBelow: "在下方插入行",
|
|
2777
|
+
deleteRow: "删除行",
|
|
2778
|
+
addColumnLeft: "在左侧插入列",
|
|
2779
|
+
addColumnRight: "在右侧插入列",
|
|
2780
|
+
deleteColumn: "删除列",
|
|
2781
|
+
mergeCells: "合并单元格",
|
|
2782
|
+
unmergeCells: "拆分单元格",
|
|
2783
|
+
columnWidth: "列宽",
|
|
2784
|
+
rowHeight: "行高",
|
|
2785
|
+
tableBorderWidth: "表格边框宽度",
|
|
2786
|
+
deleteTable: "删除表格",
|
|
2787
|
+
columnWidthPx: "列宽 (px)",
|
|
2788
|
+
rowHeightPx: "行高 (px)",
|
|
2789
|
+
tableBorderWidthPx: "表格边框宽度 (px)",
|
|
2790
|
+
cancelBtn: "取消",
|
|
2791
|
+
applyBtn: "应用"
|
|
2792
|
+
},
|
|
2793
|
+
video: {
|
|
2794
|
+
ariaLabel: "视频操作",
|
|
2795
|
+
label: "视频",
|
|
2796
|
+
floatLeft: "左浮动",
|
|
2797
|
+
noFloat: "不浮动",
|
|
2798
|
+
alignCenter: "居中对齐",
|
|
2799
|
+
floatRight: "右浮动",
|
|
2800
|
+
originalSize: "原始尺寸",
|
|
2801
|
+
previewVideo: "预览视频",
|
|
2802
|
+
exitPreview: "退出预览",
|
|
2803
|
+
deleteVideo: "删除视频"
|
|
2804
|
+
}
|
|
2805
|
+
},
|
|
2806
|
+
errors: {
|
|
2807
|
+
imageFormat: (type) => `格式 "${type}" 不支持在浏览器中显示。请转换为 JPEG、PNG 或 WebP。`,
|
|
2808
|
+
imageSize: (maxSize) => `图片文件过大。最大允许大小为 ${maxSize} MB。`
|
|
2809
|
+
}
|
|
2810
|
+
},
|
|
2811
|
+
fr: {
|
|
2812
|
+
toolbar: {
|
|
2813
|
+
bold: "Gras (Ctrl+B)",
|
|
2814
|
+
italic: "Italique (Ctrl+I)",
|
|
2815
|
+
underline: "Souligné (Ctrl+U)",
|
|
2816
|
+
strikethrough: "Barré",
|
|
2817
|
+
superscript: "Exposant",
|
|
2818
|
+
subscript: "Indice",
|
|
2819
|
+
alignLeft: "Aligner à gauche",
|
|
2820
|
+
alignCenter: "Centrer",
|
|
2821
|
+
alignRight: "Aligner à droite",
|
|
2822
|
+
alignJustify: "Justifier",
|
|
2823
|
+
ul: "Liste à puces",
|
|
2824
|
+
ol: "Liste numérotée",
|
|
2825
|
+
checklist: "Liste de tâches",
|
|
2826
|
+
indent: "Augmenter le retrait",
|
|
2827
|
+
outdent: "Diminuer le retrait",
|
|
2828
|
+
undo: "Annuler (Ctrl+Z)",
|
|
2829
|
+
redo: "Rétablir (Ctrl+Y)",
|
|
2830
|
+
hr: "Ligne horizontale",
|
|
2831
|
+
link: "Insérer un lien",
|
|
2832
|
+
image: "Insérer une image",
|
|
2833
|
+
video: "Insérer une vidéo",
|
|
2834
|
+
emoji: "Insérer un emoji",
|
|
2835
|
+
icon: "Insérer une icône FA",
|
|
2836
|
+
table: "Insérer un tableau",
|
|
2837
|
+
fontSize: "Taille de police",
|
|
2838
|
+
fontSizePlaceholder: "Taille",
|
|
2839
|
+
removeFormat: "Effacer la mise en forme",
|
|
2840
|
+
direction: "Basculer la direction du texte (LTR / RTL)",
|
|
2841
|
+
fontFamily: "Police",
|
|
2842
|
+
paragraphStyle: "Style de paragraphe",
|
|
2843
|
+
paragraphStylePlaceholder: "Style",
|
|
2844
|
+
lineHeight: "Interligne",
|
|
2845
|
+
lineHeightPlaceholder: "↕ Ligne",
|
|
2846
|
+
codeview: "Afficher le code HTML",
|
|
2847
|
+
fullscreen: "Plein écran",
|
|
2848
|
+
shortcuts: "Raccourcis clavier (Ctrl+Shift+/)",
|
|
2849
|
+
find: "Rechercher (Ctrl+F)",
|
|
2850
|
+
findReplace: "Rechercher et remplacer (Ctrl+H)",
|
|
2851
|
+
inlineCode: "Code inline (Ctrl+`)",
|
|
2852
|
+
print: "Imprimer",
|
|
2853
|
+
foreColor: "Couleur du texte",
|
|
2854
|
+
backColor: "Couleur de surbrillance",
|
|
2855
|
+
chooseTextColor: "Choisir la couleur du texte",
|
|
2856
|
+
chooseHighlightColor: "Choisir la couleur de surbrillance",
|
|
2857
|
+
customColor: "Couleur personnalisée",
|
|
2858
|
+
insertTableLabel: "Insérer un tableau",
|
|
2859
|
+
paragraphItems: {
|
|
2860
|
+
p: "Normal",
|
|
2861
|
+
blockquote: "Citation",
|
|
2862
|
+
pre: "Code"
|
|
2863
|
+
}
|
|
2864
|
+
},
|
|
2865
|
+
linkDialog: {
|
|
2866
|
+
ariaLabel: "Insérer un lien",
|
|
2867
|
+
title: "Insérer un lien",
|
|
2868
|
+
url: "URL",
|
|
2869
|
+
urlPlaceholder: "https://",
|
|
2870
|
+
displayText: "Texte affiché",
|
|
2871
|
+
textPlaceholder: "Texte du lien",
|
|
2872
|
+
openInNewTab: "Ouvrir dans un nouvel onglet",
|
|
2873
|
+
insertBtn: "Insérer",
|
|
2874
|
+
cancelBtn: "Annuler"
|
|
2875
|
+
},
|
|
2876
|
+
imageDialog: {
|
|
2877
|
+
ariaLabel: "Insérer une image",
|
|
2878
|
+
title: "Insérer une image",
|
|
2879
|
+
imageUrl: "URL de l'image",
|
|
2880
|
+
urlPlaceholder: "https://example.com/image.png",
|
|
2881
|
+
altText: "Texte alternatif",
|
|
2882
|
+
altPlaceholder: "Description de l'image",
|
|
2883
|
+
alignment: "Alignement",
|
|
2884
|
+
alignNone: "Aucun",
|
|
2885
|
+
alignLeft: "Gauche",
|
|
2886
|
+
alignCenter: "Centre",
|
|
2887
|
+
alignRight: "Droite",
|
|
2888
|
+
uploadLabel: "Ou téléverser un fichier",
|
|
2889
|
+
insertBtn: "Insérer",
|
|
2890
|
+
cancelBtn: "Annuler"
|
|
2891
|
+
},
|
|
2892
|
+
videoDialog: {
|
|
2893
|
+
ariaLabel: "Insérer une vidéo",
|
|
2894
|
+
title: "Insérer une vidéo",
|
|
2895
|
+
videoUrl: "URL de la vidéo",
|
|
2896
|
+
urlPlaceholder: "YouTube, Vimeo ou URL .mp4 directe",
|
|
2897
|
+
widthLabel: "Largeur (px)",
|
|
2898
|
+
widthPlaceholder: "560",
|
|
2899
|
+
insertBtn: "Insérer",
|
|
2900
|
+
cancelBtn: "Annuler",
|
|
2901
|
+
detected: (type) => `Détecté\u00a0: ${type}`,
|
|
2902
|
+
unknownFormat: "Format inconnu — tentative d'intégration directe",
|
|
2903
|
+
invalidUrl: "URL invalide — veuillez saisir un lien vidéo valide."
|
|
2904
|
+
},
|
|
2905
|
+
emojiDialog: {
|
|
2906
|
+
ariaLabel: "Insérer un emoji",
|
|
2907
|
+
title: "Insérer un emoji",
|
|
2908
|
+
searchPlaceholder: "Rechercher des emojis…",
|
|
2909
|
+
all: "Tout",
|
|
2910
|
+
cancelBtn: "Annuler",
|
|
2911
|
+
close: "Fermer",
|
|
2912
|
+
categories: {
|
|
2913
|
+
smileys: "Smileys",
|
|
2914
|
+
people: "Personnes",
|
|
2915
|
+
animals: "Animaux",
|
|
2916
|
+
food: "Nourriture",
|
|
2917
|
+
travel: "Voyage",
|
|
2918
|
+
objects: "Objets",
|
|
2919
|
+
symbols: "Symboles"
|
|
2920
|
+
}
|
|
2921
|
+
},
|
|
2922
|
+
iconDialog: {
|
|
2923
|
+
ariaLabel: "Insérer une icône FA",
|
|
2924
|
+
title: "Insérer une icône FA",
|
|
2925
|
+
searchPlaceholder: "Rechercher des icônes…",
|
|
2926
|
+
all: "Tout",
|
|
2927
|
+
style: "Style",
|
|
2928
|
+
size: "Taille",
|
|
2929
|
+
color: "Couleur",
|
|
2930
|
+
useColor: " Utiliser la couleur",
|
|
2931
|
+
selectHint: "Sélectionner une icône",
|
|
2932
|
+
insertBtn: "Insérer une icône FA",
|
|
2933
|
+
cancelBtn: "Annuler",
|
|
2934
|
+
close: "Fermer",
|
|
2935
|
+
categories: {
|
|
2936
|
+
popular: "Populaire",
|
|
2937
|
+
interface: "Interface",
|
|
2938
|
+
navigation: "Navigation",
|
|
2939
|
+
media: "Média",
|
|
2940
|
+
communication: "Communication",
|
|
2941
|
+
files: "Fichiers",
|
|
2942
|
+
people: "Personnes",
|
|
2943
|
+
objects: "Objets"
|
|
2944
|
+
}
|
|
2945
|
+
},
|
|
2946
|
+
findReplace: {
|
|
2947
|
+
findTitle: "Rechercher",
|
|
2948
|
+
findReplaceTitle: "Rechercher et remplacer",
|
|
2949
|
+
findPlaceholder: "Rechercher…",
|
|
2950
|
+
searchAriaLabel: "Texte à rechercher",
|
|
2951
|
+
caseSensitive: "\xA0Respecter la casse",
|
|
2952
|
+
prevBtn: "← Préc.",
|
|
2953
|
+
nextBtn: "Suiv. →",
|
|
2954
|
+
replacePlaceholder: "Remplacer par…",
|
|
2955
|
+
replaceAriaLabel: "Remplacer par",
|
|
2956
|
+
replaceBtn: "Remplacer",
|
|
2957
|
+
replaceAllBtn: "Tout remplacer",
|
|
2958
|
+
close: "×"
|
|
2959
|
+
},
|
|
2960
|
+
shortcutsDialog: {
|
|
2961
|
+
title: "Raccourcis clavier",
|
|
2962
|
+
ariaLabel: "Raccourcis clavier",
|
|
2963
|
+
close: "Fermer",
|
|
2964
|
+
shortcuts: [
|
|
2965
|
+
{
|
|
2966
|
+
category: "Mise en forme du texte",
|
|
2967
|
+
items: [
|
|
2968
|
+
{
|
|
2969
|
+
keys: "Ctrl + B",
|
|
2970
|
+
action: "Gras"
|
|
2971
|
+
},
|
|
2972
|
+
{
|
|
2973
|
+
keys: "Ctrl + I",
|
|
2974
|
+
action: "Italique"
|
|
2975
|
+
},
|
|
2976
|
+
{
|
|
2977
|
+
keys: "Ctrl + U",
|
|
2978
|
+
action: "Souligné"
|
|
2979
|
+
},
|
|
2980
|
+
{
|
|
2981
|
+
keys: "Ctrl + K",
|
|
2982
|
+
action: "Insérer / modifier un lien"
|
|
2983
|
+
}
|
|
2984
|
+
]
|
|
2985
|
+
},
|
|
2986
|
+
{
|
|
2987
|
+
category: "Historique",
|
|
2988
|
+
items: [{
|
|
2989
|
+
keys: "Ctrl + Z",
|
|
2990
|
+
action: "Annuler"
|
|
2991
|
+
}, {
|
|
2992
|
+
keys: "Ctrl + Y / Ctrl + Shift + Z",
|
|
2993
|
+
action: "Rétablir"
|
|
2994
|
+
}]
|
|
2995
|
+
},
|
|
2996
|
+
{
|
|
2997
|
+
category: "Sélection et navigation",
|
|
2998
|
+
items: [
|
|
2999
|
+
{
|
|
3000
|
+
keys: "Ctrl + A",
|
|
3001
|
+
action: "Tout sélectionner"
|
|
3002
|
+
},
|
|
3003
|
+
{
|
|
3004
|
+
keys: "Tab",
|
|
3005
|
+
action: "Augmenter le retrait / insérer des espaces"
|
|
3006
|
+
},
|
|
3007
|
+
{
|
|
3008
|
+
keys: "Shift + Tab",
|
|
3009
|
+
action: "Diminuer le retrait"
|
|
3010
|
+
}
|
|
3011
|
+
]
|
|
3012
|
+
},
|
|
3013
|
+
{
|
|
3014
|
+
category: "Presse-papiers",
|
|
3015
|
+
items: [{
|
|
3016
|
+
keys: "Ctrl + Shift + V",
|
|
3017
|
+
action: "Coller en texte brut"
|
|
3018
|
+
}]
|
|
3019
|
+
},
|
|
3020
|
+
{
|
|
3021
|
+
category: "Rechercher et remplacer",
|
|
3022
|
+
items: [{
|
|
3023
|
+
keys: "Ctrl + F",
|
|
3024
|
+
action: "Rechercher dans le document"
|
|
3025
|
+
}, {
|
|
3026
|
+
keys: "Ctrl + H",
|
|
3027
|
+
action: "Rechercher et remplacer"
|
|
3028
|
+
}]
|
|
3029
|
+
},
|
|
3030
|
+
{
|
|
3031
|
+
category: "Éditeur",
|
|
3032
|
+
items: [{
|
|
3033
|
+
keys: "Ctrl + Shift + /",
|
|
3034
|
+
action: "Afficher les raccourcis clavier"
|
|
3035
|
+
}]
|
|
3036
|
+
}
|
|
3037
|
+
]
|
|
3038
|
+
},
|
|
3039
|
+
contextMenu: {
|
|
3040
|
+
cut: "Couper",
|
|
3041
|
+
copy: "Copier",
|
|
3042
|
+
paste: "Coller",
|
|
3043
|
+
bold: "Gras",
|
|
3044
|
+
italic: "Italique",
|
|
3045
|
+
underline: "Souligné",
|
|
3046
|
+
textColor: "Couleur du texte",
|
|
3047
|
+
highlightColor: "Couleur de surbrillance",
|
|
3048
|
+
copyFormat: "Copier la mise en forme",
|
|
3049
|
+
pasteFormat: "Coller la mise en forme",
|
|
3050
|
+
removeFormat: "Effacer la mise en forme",
|
|
3051
|
+
link: "Insérer un lien",
|
|
3052
|
+
image: "Insérer une image",
|
|
3053
|
+
video: "Insérer une vidéo",
|
|
3054
|
+
table: "Insérer un tableau",
|
|
3055
|
+
back: "Retour",
|
|
3056
|
+
noHighlight: "Sans surbrillance",
|
|
3057
|
+
customColor: "Couleur personnalisée",
|
|
3058
|
+
customColorLabel: "Personnaliser…"
|
|
3059
|
+
},
|
|
3060
|
+
statusbar: {
|
|
3061
|
+
resizeHandle: "Faire glisser pour redimensionner",
|
|
3062
|
+
words: (n) => `Mots\u00a0: ${n}`,
|
|
3063
|
+
wordsLimit: (n, max) => `Mots\u00a0: ${n}/${max}`,
|
|
3064
|
+
chars: (n) => `Caractères\u00a0: ${n}`,
|
|
3065
|
+
charsLimit: (n, max) => `Caractères\u00a0: ${n}/${max}`
|
|
3066
|
+
},
|
|
3067
|
+
tooltips: {
|
|
3068
|
+
link: {
|
|
3069
|
+
ariaLabel: "Actions du lien",
|
|
3070
|
+
openLink: "Ouvrir le lien",
|
|
3071
|
+
copyUrl: "Copier l'URL",
|
|
3072
|
+
editLink: "Modifier le lien",
|
|
3073
|
+
removeLink: "Supprimer le lien"
|
|
3074
|
+
},
|
|
3075
|
+
image: {
|
|
3076
|
+
ariaLabel: "Actions de l'image",
|
|
3077
|
+
label: "Image",
|
|
3078
|
+
floatLeft: "Flottant à gauche",
|
|
3079
|
+
noFloat: "Sans flottant",
|
|
3080
|
+
alignCenter: "Centré",
|
|
3081
|
+
floatRight: "Flottant à droite",
|
|
3082
|
+
originalSize: "Taille originale",
|
|
3083
|
+
rotateLeft: "Rotation à gauche",
|
|
3084
|
+
rotateRight: "Rotation à droite",
|
|
3085
|
+
cropImage: "Recadrer l'image",
|
|
3086
|
+
addCaption: "Ajouter / modifier la légende",
|
|
3087
|
+
deleteImage: "Supprimer l'image"
|
|
3088
|
+
},
|
|
3089
|
+
code: {
|
|
3090
|
+
ariaLabel: "Actions du bloc de code",
|
|
3091
|
+
label: "Code",
|
|
3092
|
+
syntaxLanguage: "Langage de syntaxe",
|
|
3093
|
+
syntaxAriaLabel: "Langage de syntaxe",
|
|
3094
|
+
copyCode: "Copier le code",
|
|
3095
|
+
toggleWordWrap: "Activer/désactiver le retour à la ligne",
|
|
3096
|
+
enableWordWrap: "Activer le retour à la ligne",
|
|
3097
|
+
disableWordWrap: "Désactiver le retour à la ligne",
|
|
3098
|
+
convertToParagraph: "Convertir en paragraphe",
|
|
3099
|
+
deleteCodeBlock: "Supprimer le bloc de code"
|
|
3100
|
+
},
|
|
3101
|
+
table: {
|
|
3102
|
+
ariaLabel: "Actions du tableau",
|
|
3103
|
+
label: "Tableau",
|
|
3104
|
+
selectCells: "Sélectionner des cellules",
|
|
3105
|
+
addRowAbove: "Ajouter une ligne au-dessus",
|
|
3106
|
+
addRowBelow: "Ajouter une ligne en-dessous",
|
|
3107
|
+
deleteRow: "Supprimer la ligne",
|
|
3108
|
+
addColumnLeft: "Ajouter une colonne à gauche",
|
|
3109
|
+
addColumnRight: "Ajouter une colonne à droite",
|
|
3110
|
+
deleteColumn: "Supprimer la colonne",
|
|
3111
|
+
mergeCells: "Fusionner les cellules",
|
|
3112
|
+
unmergeCells: "Scinder les cellules",
|
|
3113
|
+
columnWidth: "Largeur de colonne",
|
|
3114
|
+
rowHeight: "Hauteur de ligne",
|
|
3115
|
+
tableBorderWidth: "Épaisseur des bordures",
|
|
3116
|
+
deleteTable: "Supprimer le tableau",
|
|
3117
|
+
columnWidthPx: "Largeur de colonne (px)",
|
|
3118
|
+
rowHeightPx: "Hauteur de ligne (px)",
|
|
3119
|
+
tableBorderWidthPx: "Épaisseur des bordures (px)",
|
|
3120
|
+
cancelBtn: "Annuler",
|
|
3121
|
+
applyBtn: "Appliquer"
|
|
3122
|
+
},
|
|
3123
|
+
video: {
|
|
3124
|
+
ariaLabel: "Actions de la vidéo",
|
|
3125
|
+
label: "Vidéo",
|
|
3126
|
+
floatLeft: "Flottant à gauche",
|
|
3127
|
+
noFloat: "Sans flottant",
|
|
3128
|
+
alignCenter: "Centré",
|
|
3129
|
+
floatRight: "Flottant à droite",
|
|
3130
|
+
originalSize: "Taille originale",
|
|
3131
|
+
previewVideo: "Aperçu",
|
|
3132
|
+
exitPreview: "Quitter l'aperçu",
|
|
3133
|
+
deleteVideo: "Supprimer la vidéo"
|
|
3134
|
+
}
|
|
3135
|
+
},
|
|
3136
|
+
errors: {
|
|
3137
|
+
imageFormat: (type) => `Le format "${type}" n'est pas pris en charge par le navigateur. Veuillez le convertir en JPEG, PNG ou WebP.`,
|
|
3138
|
+
imageSize: (maxSize) => `Le fichier image est trop volumineux. La taille maximale autorisée est de ${maxSize}\u00a0Mo.`
|
|
3139
|
+
}
|
|
3140
|
+
},
|
|
3141
|
+
de: {
|
|
3142
|
+
toolbar: {
|
|
3143
|
+
bold: "Fett (Ctrl+B)",
|
|
3144
|
+
italic: "Kursiv (Ctrl+I)",
|
|
3145
|
+
underline: "Unterstrichen (Ctrl+U)",
|
|
3146
|
+
strikethrough: "Durchgestrichen",
|
|
3147
|
+
superscript: "Hochgestellt",
|
|
3148
|
+
subscript: "Tiefgestellt",
|
|
3149
|
+
alignLeft: "Linksbündig",
|
|
3150
|
+
alignCenter: "Zentriert",
|
|
3151
|
+
alignRight: "Rechtsbündig",
|
|
3152
|
+
alignJustify: "Blocksatz",
|
|
3153
|
+
ul: "Ungeordnete Liste",
|
|
3154
|
+
ol: "Geordnete Liste",
|
|
3155
|
+
checklist: "Checkliste",
|
|
3156
|
+
indent: "Einzug vergrößern",
|
|
3157
|
+
outdent: "Einzug verkleinern",
|
|
3158
|
+
undo: "Rückgängig (Ctrl+Z)",
|
|
3159
|
+
redo: "Wiederholen (Ctrl+Y)",
|
|
3160
|
+
hr: "Horizontale Linie",
|
|
3161
|
+
link: "Link einfügen",
|
|
3162
|
+
image: "Bild einfügen",
|
|
3163
|
+
video: "Video einfügen",
|
|
3164
|
+
emoji: "Emoji einfügen",
|
|
3165
|
+
icon: "FA-Symbol einfügen",
|
|
3166
|
+
table: "Tabelle einfügen",
|
|
3167
|
+
fontSize: "Schriftgröße",
|
|
3168
|
+
fontSizePlaceholder: "Größe",
|
|
3169
|
+
removeFormat: "Formatierung entfernen",
|
|
3170
|
+
direction: "Textrichtung umschalten (LTR / RTL)",
|
|
3171
|
+
fontFamily: "Schriftart",
|
|
3172
|
+
paragraphStyle: "Absatzstil",
|
|
3173
|
+
paragraphStylePlaceholder: "Stil",
|
|
3174
|
+
lineHeight: "Zeilenhöhe",
|
|
3175
|
+
lineHeightPlaceholder: "↕ Zeile",
|
|
3176
|
+
codeview: "HTML-Code-Ansicht",
|
|
3177
|
+
fullscreen: "Vollbild",
|
|
3178
|
+
shortcuts: "Tastenkürzel (Ctrl+Shift+/)",
|
|
3179
|
+
find: "Suchen (Ctrl+F)",
|
|
3180
|
+
findReplace: "Suchen & Ersetzen (Ctrl+H)",
|
|
3181
|
+
inlineCode: "Inline-Code (Ctrl+`)",
|
|
3182
|
+
print: "Drucken",
|
|
3183
|
+
foreColor: "Textfarbe",
|
|
3184
|
+
backColor: "Hervorhebungsfarbe",
|
|
3185
|
+
chooseTextColor: "Textfarbe auswählen",
|
|
3186
|
+
chooseHighlightColor: "Hervorhebungsfarbe auswählen",
|
|
3187
|
+
customColor: "Benutzerdefinierte Farbe",
|
|
3188
|
+
insertTableLabel: "Tabelle einfügen",
|
|
3189
|
+
paragraphItems: {
|
|
3190
|
+
p: "Normal",
|
|
3191
|
+
blockquote: "Zitat",
|
|
3192
|
+
pre: "Code"
|
|
3193
|
+
}
|
|
3194
|
+
},
|
|
3195
|
+
linkDialog: {
|
|
3196
|
+
ariaLabel: "Link einfügen",
|
|
3197
|
+
title: "Link einfügen",
|
|
3198
|
+
url: "URL",
|
|
3199
|
+
urlPlaceholder: "https://",
|
|
3200
|
+
displayText: "Anzeigetext",
|
|
3201
|
+
textPlaceholder: "Linktext",
|
|
3202
|
+
openInNewTab: "In neuem Tab öffnen",
|
|
3203
|
+
insertBtn: "Einfügen",
|
|
3204
|
+
cancelBtn: "Abbrechen"
|
|
3205
|
+
},
|
|
3206
|
+
imageDialog: {
|
|
3207
|
+
ariaLabel: "Bild einfügen",
|
|
3208
|
+
title: "Bild einfügen",
|
|
3209
|
+
imageUrl: "Bild-URL",
|
|
3210
|
+
urlPlaceholder: "https://example.com/image.png",
|
|
3211
|
+
altText: "Alt-Text",
|
|
3212
|
+
altPlaceholder: "Bild beschreiben",
|
|
3213
|
+
alignment: "Ausrichtung",
|
|
3214
|
+
alignNone: "Keine",
|
|
3215
|
+
alignLeft: "Links",
|
|
3216
|
+
alignCenter: "Mitte",
|
|
3217
|
+
alignRight: "Rechts",
|
|
3218
|
+
uploadLabel: "Oder Datei hochladen",
|
|
3219
|
+
insertBtn: "Einfügen",
|
|
3220
|
+
cancelBtn: "Abbrechen"
|
|
3221
|
+
},
|
|
3222
|
+
videoDialog: {
|
|
3223
|
+
ariaLabel: "Video einfügen",
|
|
3224
|
+
title: "Video einfügen",
|
|
3225
|
+
videoUrl: "Video-URL",
|
|
3226
|
+
urlPlaceholder: "YouTube, Vimeo oder direkte .mp4-URL",
|
|
3227
|
+
widthLabel: "Breite (px)",
|
|
3228
|
+
widthPlaceholder: "560",
|
|
3229
|
+
insertBtn: "Einfügen",
|
|
3230
|
+
cancelBtn: "Abbrechen",
|
|
3231
|
+
detected: (type) => `Erkannt: ${type}`,
|
|
3232
|
+
unknownFormat: "Unbekanntes Format — direktes Video-Einbetten wird versucht",
|
|
3233
|
+
invalidUrl: "Ungültige URL — bitte geben Sie einen gültigen Videolink ein."
|
|
3234
|
+
},
|
|
3235
|
+
emojiDialog: {
|
|
3236
|
+
ariaLabel: "Emoji einfügen",
|
|
3237
|
+
title: "Emoji einfügen",
|
|
3238
|
+
searchPlaceholder: "Emojis suchen…",
|
|
3239
|
+
all: "Alle",
|
|
3240
|
+
cancelBtn: "Abbrechen",
|
|
3241
|
+
close: "Schließen",
|
|
3242
|
+
categories: {
|
|
3243
|
+
smileys: "Smileys",
|
|
3244
|
+
people: "Menschen",
|
|
3245
|
+
animals: "Tiere",
|
|
3246
|
+
food: "Essen",
|
|
3247
|
+
travel: "Reisen",
|
|
3248
|
+
objects: "Objekte",
|
|
3249
|
+
symbols: "Symbole"
|
|
3250
|
+
}
|
|
3251
|
+
},
|
|
3252
|
+
iconDialog: {
|
|
3253
|
+
ariaLabel: "FA-Symbol einfügen",
|
|
3254
|
+
title: "FA-Symbol einfügen",
|
|
3255
|
+
searchPlaceholder: "Symbole suchen…",
|
|
3256
|
+
all: "Alle",
|
|
3257
|
+
style: "Stil",
|
|
3258
|
+
size: "Größe",
|
|
3259
|
+
color: "Farbe",
|
|
3260
|
+
useColor: " Farbe verwenden",
|
|
3261
|
+
selectHint: "Symbol auswählen",
|
|
3262
|
+
insertBtn: "FA-Symbol einfügen",
|
|
3263
|
+
cancelBtn: "Abbrechen",
|
|
3264
|
+
close: "Schließen",
|
|
3265
|
+
categories: {
|
|
3266
|
+
popular: "Beliebt",
|
|
3267
|
+
interface: "Benutzeroberfläche",
|
|
3268
|
+
navigation: "Navigation",
|
|
3269
|
+
media: "Medien",
|
|
3270
|
+
communication: "Kommunikation",
|
|
3271
|
+
files: "Dateien",
|
|
3272
|
+
people: "Menschen",
|
|
3273
|
+
objects: "Objekte"
|
|
3274
|
+
}
|
|
3275
|
+
},
|
|
3276
|
+
findReplace: {
|
|
3277
|
+
findTitle: "Suchen",
|
|
3278
|
+
findReplaceTitle: "Suchen & Ersetzen",
|
|
3279
|
+
findPlaceholder: "Suchen…",
|
|
3280
|
+
searchAriaLabel: "Suchtext",
|
|
3281
|
+
caseSensitive: "\xA0Groß-/Kleinschreibung",
|
|
3282
|
+
prevBtn: "← Zurück",
|
|
3283
|
+
nextBtn: "Weiter →",
|
|
3284
|
+
replacePlaceholder: "Ersetzen durch…",
|
|
3285
|
+
replaceAriaLabel: "Ersetzen durch",
|
|
3286
|
+
replaceBtn: "Ersetzen",
|
|
3287
|
+
replaceAllBtn: "Alle ersetzen",
|
|
3288
|
+
close: "×"
|
|
3289
|
+
},
|
|
3290
|
+
shortcutsDialog: {
|
|
3291
|
+
title: "Tastenkürzel",
|
|
3292
|
+
ariaLabel: "Tastenkürzel",
|
|
3293
|
+
close: "Schließen",
|
|
3294
|
+
shortcuts: [
|
|
3295
|
+
{
|
|
3296
|
+
category: "Textformatierung",
|
|
3297
|
+
items: [
|
|
3298
|
+
{
|
|
3299
|
+
keys: "Ctrl + B",
|
|
3300
|
+
action: "Fett"
|
|
3301
|
+
},
|
|
3302
|
+
{
|
|
3303
|
+
keys: "Ctrl + I",
|
|
3304
|
+
action: "Kursiv"
|
|
3305
|
+
},
|
|
3306
|
+
{
|
|
3307
|
+
keys: "Ctrl + U",
|
|
3308
|
+
action: "Unterstrichen"
|
|
3309
|
+
},
|
|
3310
|
+
{
|
|
3311
|
+
keys: "Ctrl + K",
|
|
3312
|
+
action: "Link einfügen / bearbeiten"
|
|
3313
|
+
}
|
|
3314
|
+
]
|
|
3315
|
+
},
|
|
3316
|
+
{
|
|
3317
|
+
category: "Verlauf",
|
|
3318
|
+
items: [{
|
|
3319
|
+
keys: "Ctrl + Z",
|
|
3320
|
+
action: "Rückgängig"
|
|
3321
|
+
}, {
|
|
3322
|
+
keys: "Ctrl + Y / Ctrl + Shift + Z",
|
|
3323
|
+
action: "Wiederholen"
|
|
3324
|
+
}]
|
|
3325
|
+
},
|
|
3326
|
+
{
|
|
3327
|
+
category: "Auswahl & Navigation",
|
|
3328
|
+
items: [
|
|
3329
|
+
{
|
|
3330
|
+
keys: "Ctrl + A",
|
|
3331
|
+
action: "Alles auswählen"
|
|
3332
|
+
},
|
|
3333
|
+
{
|
|
3334
|
+
keys: "Tab",
|
|
3335
|
+
action: "Listenebene erhöhen / Leerzeichen einfügen"
|
|
3336
|
+
},
|
|
3337
|
+
{
|
|
3338
|
+
keys: "Shift + Tab",
|
|
3339
|
+
action: "Listenebene verringern"
|
|
3340
|
+
}
|
|
3341
|
+
]
|
|
3342
|
+
},
|
|
3343
|
+
{
|
|
3344
|
+
category: "Zwischenablage",
|
|
3345
|
+
items: [{
|
|
3346
|
+
keys: "Ctrl + Shift + V",
|
|
3347
|
+
action: "Als einfachen Text einfügen"
|
|
3348
|
+
}]
|
|
3349
|
+
},
|
|
3350
|
+
{
|
|
3351
|
+
category: "Suchen & Ersetzen",
|
|
3352
|
+
items: [{
|
|
3353
|
+
keys: "Ctrl + F",
|
|
3354
|
+
action: "Im Dokument suchen"
|
|
3355
|
+
}, {
|
|
3356
|
+
keys: "Ctrl + H",
|
|
3357
|
+
action: "Suchen & Ersetzen"
|
|
3358
|
+
}]
|
|
3359
|
+
},
|
|
3360
|
+
{
|
|
3361
|
+
category: "Editor",
|
|
3362
|
+
items: [{
|
|
3363
|
+
keys: "Ctrl + Shift + /",
|
|
3364
|
+
action: "Diesen Tastenkürzel-Dialog anzeigen"
|
|
3365
|
+
}]
|
|
3366
|
+
}
|
|
3367
|
+
]
|
|
3368
|
+
},
|
|
3369
|
+
contextMenu: {
|
|
3370
|
+
cut: "Ausschneiden",
|
|
3371
|
+
copy: "Kopieren",
|
|
3372
|
+
paste: "Einfügen",
|
|
3373
|
+
bold: "Fett",
|
|
3374
|
+
italic: "Kursiv",
|
|
3375
|
+
underline: "Unterstrichen",
|
|
3376
|
+
textColor: "Textfarbe",
|
|
3377
|
+
highlightColor: "Hervorhebungsfarbe",
|
|
3378
|
+
copyFormat: "Format kopieren",
|
|
3379
|
+
pasteFormat: "Format einfügen",
|
|
3380
|
+
removeFormat: "Formatierung entfernen",
|
|
3381
|
+
link: "Link einfügen",
|
|
3382
|
+
image: "Bild einfügen",
|
|
3383
|
+
video: "Video einfügen",
|
|
3384
|
+
table: "Tabelle einfügen",
|
|
3385
|
+
back: "Zurück",
|
|
3386
|
+
noHighlight: "Keine Hervorhebung",
|
|
3387
|
+
customColor: "Benutzerdefinierte Farbe",
|
|
3388
|
+
customColorLabel: "Benutzerdefiniert…"
|
|
3389
|
+
},
|
|
3390
|
+
statusbar: {
|
|
3391
|
+
resizeHandle: "Editor-Größe ändern",
|
|
3392
|
+
words: (n) => `Wörter: ${n}`,
|
|
3393
|
+
wordsLimit: (n, max) => `Wörter: ${n}/${max}`,
|
|
3394
|
+
chars: (n) => `Zeichen: ${n}`,
|
|
3395
|
+
charsLimit: (n, max) => `Zeichen: ${n}/${max}`
|
|
3396
|
+
},
|
|
3397
|
+
tooltips: {
|
|
3398
|
+
link: {
|
|
3399
|
+
ariaLabel: "Link-Aktionen",
|
|
3400
|
+
openLink: "Link öffnen",
|
|
3401
|
+
copyUrl: "URL kopieren",
|
|
3402
|
+
editLink: "Link bearbeiten",
|
|
3403
|
+
removeLink: "Link entfernen"
|
|
3404
|
+
},
|
|
3405
|
+
image: {
|
|
3406
|
+
ariaLabel: "Bild-Aktionen",
|
|
3407
|
+
label: "Bild",
|
|
3408
|
+
floatLeft: "Links umfließen",
|
|
3409
|
+
noFloat: "Kein Umfluss",
|
|
3410
|
+
alignCenter: "Zentriert",
|
|
3411
|
+
floatRight: "Rechts umfließen",
|
|
3412
|
+
originalSize: "Originalgröße",
|
|
3413
|
+
rotateLeft: "Links drehen",
|
|
3414
|
+
rotateRight: "Rechts drehen",
|
|
3415
|
+
cropImage: "Bild zuschneiden",
|
|
3416
|
+
addCaption: "Beschriftung hinzufügen / bearbeiten",
|
|
3417
|
+
deleteImage: "Bild löschen"
|
|
3418
|
+
},
|
|
3419
|
+
code: {
|
|
3420
|
+
ariaLabel: "Codeblock-Aktionen",
|
|
3421
|
+
label: "Code",
|
|
3422
|
+
syntaxLanguage: "Syntaxsprache",
|
|
3423
|
+
syntaxAriaLabel: "Syntaxsprache",
|
|
3424
|
+
copyCode: "Code kopieren",
|
|
3425
|
+
toggleWordWrap: "Zeilenumbruch umschalten",
|
|
3426
|
+
enableWordWrap: "Zeilenumbruch aktivieren",
|
|
3427
|
+
disableWordWrap: "Zeilenumbruch deaktivieren",
|
|
3428
|
+
convertToParagraph: "In Absatz umwandeln",
|
|
3429
|
+
deleteCodeBlock: "Codeblock löschen"
|
|
3430
|
+
},
|
|
3431
|
+
table: {
|
|
3432
|
+
ariaLabel: "Tabellen-Aktionen",
|
|
3433
|
+
label: "Tabelle",
|
|
3434
|
+
selectCells: "Zellen auswählen",
|
|
3435
|
+
addRowAbove: "Zeile oben hinzufügen",
|
|
3436
|
+
addRowBelow: "Zeile unten hinzufügen",
|
|
3437
|
+
deleteRow: "Zeile löschen",
|
|
3438
|
+
addColumnLeft: "Spalte links hinzufügen",
|
|
3439
|
+
addColumnRight: "Spalte rechts hinzufügen",
|
|
3440
|
+
deleteColumn: "Spalte löschen",
|
|
3441
|
+
mergeCells: "Zellen zusammenführen",
|
|
3442
|
+
unmergeCells: "Zellen trennen",
|
|
3443
|
+
columnWidth: "Spaltenbreite",
|
|
3444
|
+
rowHeight: "Zeilenhöhe",
|
|
3445
|
+
tableBorderWidth: "Tabellenrahmenbreite",
|
|
3446
|
+
deleteTable: "Tabelle löschen",
|
|
3447
|
+
columnWidthPx: "Spaltenbreite (px)",
|
|
3448
|
+
rowHeightPx: "Zeilenhöhe (px)",
|
|
3449
|
+
tableBorderWidthPx: "Tabellenrahmenbreite (px)",
|
|
3450
|
+
cancelBtn: "Abbrechen",
|
|
3451
|
+
applyBtn: "Anwenden"
|
|
3452
|
+
},
|
|
3453
|
+
video: {
|
|
3454
|
+
ariaLabel: "Video-Aktionen",
|
|
3455
|
+
label: "Video",
|
|
3456
|
+
floatLeft: "Links umfließen",
|
|
3457
|
+
noFloat: "Kein Umfluss",
|
|
3458
|
+
alignCenter: "Zentriert",
|
|
3459
|
+
floatRight: "Rechts umfließen",
|
|
3460
|
+
originalSize: "Originalgröße",
|
|
3461
|
+
previewVideo: "Video-Vorschau",
|
|
3462
|
+
exitPreview: "Vorschau beenden",
|
|
3463
|
+
deleteVideo: "Video löschen"
|
|
3464
|
+
}
|
|
3465
|
+
},
|
|
3466
|
+
errors: {
|
|
3467
|
+
imageFormat: (type) => `Das Format „${type}" wird in Webbrowsern nicht unterstützt. Bitte konvertieren Sie es zuerst in JPEG, PNG oder WebP.`,
|
|
3468
|
+
imageSize: (maxSize) => `Die Bilddatei ist zu groß. Die maximal zulässige Größe beträgt ${maxSize} MB.`
|
|
3469
|
+
}
|
|
3470
|
+
},
|
|
3471
|
+
es: {
|
|
3472
|
+
toolbar: {
|
|
3473
|
+
bold: "Negrita (Ctrl+B)",
|
|
3474
|
+
italic: "Cursiva (Ctrl+I)",
|
|
3475
|
+
underline: "Subrayado (Ctrl+U)",
|
|
3476
|
+
strikethrough: "Tachado",
|
|
3477
|
+
superscript: "Superíndice",
|
|
3478
|
+
subscript: "Subíndice",
|
|
3479
|
+
alignLeft: "Alinear a la izquierda",
|
|
3480
|
+
alignCenter: "Centrar",
|
|
3481
|
+
alignRight: "Alinear a la derecha",
|
|
3482
|
+
alignJustify: "Justificar",
|
|
3483
|
+
ul: "Lista sin orden",
|
|
3484
|
+
ol: "Lista ordenada",
|
|
3485
|
+
checklist: "Lista de verificación",
|
|
3486
|
+
indent: "Aumentar sangría",
|
|
3487
|
+
outdent: "Reducir sangría",
|
|
3488
|
+
undo: "Deshacer (Ctrl+Z)",
|
|
3489
|
+
redo: "Rehacer (Ctrl+Y)",
|
|
3490
|
+
hr: "Línea horizontal",
|
|
3491
|
+
link: "Insertar enlace",
|
|
3492
|
+
image: "Insertar imagen",
|
|
3493
|
+
video: "Insertar vídeo",
|
|
3494
|
+
emoji: "Insertar emoji",
|
|
3495
|
+
icon: "Insertar icono FA",
|
|
3496
|
+
table: "Insertar tabla",
|
|
3497
|
+
fontSize: "Tamaño de fuente",
|
|
3498
|
+
fontSizePlaceholder: "Tamaño",
|
|
3499
|
+
removeFormat: "Eliminar formato",
|
|
3500
|
+
direction: "Cambiar dirección del texto (LTR / RTL)",
|
|
3501
|
+
fontFamily: "Fuente",
|
|
3502
|
+
paragraphStyle: "Estilo de párrafo",
|
|
3503
|
+
paragraphStylePlaceholder: "Estilo",
|
|
3504
|
+
lineHeight: "Interlineado",
|
|
3505
|
+
lineHeightPlaceholder: "↕ Línea",
|
|
3506
|
+
codeview: "Vista de código HTML",
|
|
3507
|
+
fullscreen: "Pantalla completa",
|
|
3508
|
+
shortcuts: "Atajos de teclado (Ctrl+Shift+/)",
|
|
3509
|
+
find: "Buscar (Ctrl+F)",
|
|
3510
|
+
findReplace: "Buscar y reemplazar (Ctrl+H)",
|
|
3511
|
+
inlineCode: "Código en línea (Ctrl+`)",
|
|
3512
|
+
print: "Imprimir",
|
|
3513
|
+
foreColor: "Color del texto",
|
|
3514
|
+
backColor: "Color de resaltado",
|
|
3515
|
+
chooseTextColor: "Elegir color del texto",
|
|
3516
|
+
chooseHighlightColor: "Elegir color de resaltado",
|
|
3517
|
+
customColor: "Color personalizado",
|
|
3518
|
+
insertTableLabel: "Insertar tabla",
|
|
3519
|
+
paragraphItems: {
|
|
3520
|
+
p: "Normal",
|
|
3521
|
+
blockquote: "Cita",
|
|
3522
|
+
pre: "Código"
|
|
3523
|
+
}
|
|
3524
|
+
},
|
|
3525
|
+
linkDialog: {
|
|
3526
|
+
ariaLabel: "Insertar enlace",
|
|
3527
|
+
title: "Insertar enlace",
|
|
3528
|
+
url: "URL",
|
|
3529
|
+
urlPlaceholder: "https://",
|
|
3530
|
+
displayText: "Texto a mostrar",
|
|
3531
|
+
textPlaceholder: "Texto del enlace",
|
|
3532
|
+
openInNewTab: "Abrir en nueva pestaña",
|
|
3533
|
+
insertBtn: "Insertar",
|
|
3534
|
+
cancelBtn: "Cancelar"
|
|
3535
|
+
},
|
|
3536
|
+
imageDialog: {
|
|
3537
|
+
ariaLabel: "Insertar imagen",
|
|
3538
|
+
title: "Insertar imagen",
|
|
3539
|
+
imageUrl: "URL de imagen",
|
|
3540
|
+
urlPlaceholder: "https://example.com/image.png",
|
|
3541
|
+
altText: "Texto alternativo",
|
|
3542
|
+
altPlaceholder: "Describir la imagen",
|
|
3543
|
+
alignment: "Alineación",
|
|
3544
|
+
alignNone: "Ninguna",
|
|
3545
|
+
alignLeft: "Izquierda",
|
|
3546
|
+
alignCenter: "Centro",
|
|
3547
|
+
alignRight: "Derecha",
|
|
3548
|
+
uploadLabel: "O subir un archivo",
|
|
3549
|
+
insertBtn: "Insertar",
|
|
3550
|
+
cancelBtn: "Cancelar"
|
|
3551
|
+
},
|
|
3552
|
+
videoDialog: {
|
|
3553
|
+
ariaLabel: "Insertar vídeo",
|
|
3554
|
+
title: "Insertar vídeo",
|
|
3555
|
+
videoUrl: "URL del vídeo",
|
|
3556
|
+
urlPlaceholder: "YouTube, Vimeo o URL directa .mp4",
|
|
3557
|
+
widthLabel: "Ancho (px)",
|
|
3558
|
+
widthPlaceholder: "560",
|
|
3559
|
+
insertBtn: "Insertar",
|
|
3560
|
+
cancelBtn: "Cancelar",
|
|
3561
|
+
detected: (type) => `Detectado: ${type}`,
|
|
3562
|
+
unknownFormat: "Formato desconocido — se intentará incrustar el vídeo directamente",
|
|
3563
|
+
invalidUrl: "URL no válida — introduzca un enlace de vídeo válido."
|
|
3564
|
+
},
|
|
3565
|
+
emojiDialog: {
|
|
3566
|
+
ariaLabel: "Insertar emoji",
|
|
3567
|
+
title: "Insertar emoji",
|
|
3568
|
+
searchPlaceholder: "Buscar emojis…",
|
|
3569
|
+
all: "Todos",
|
|
3570
|
+
cancelBtn: "Cancelar",
|
|
3571
|
+
close: "Cerrar",
|
|
3572
|
+
categories: {
|
|
3573
|
+
smileys: "Caritas",
|
|
3574
|
+
people: "Personas",
|
|
3575
|
+
animals: "Animales",
|
|
3576
|
+
food: "Comida",
|
|
3577
|
+
travel: "Viajes",
|
|
3578
|
+
objects: "Objetos",
|
|
3579
|
+
symbols: "Símbolos"
|
|
3580
|
+
}
|
|
3581
|
+
},
|
|
3582
|
+
iconDialog: {
|
|
3583
|
+
ariaLabel: "Insertar icono FA",
|
|
3584
|
+
title: "Insertar icono FA",
|
|
3585
|
+
searchPlaceholder: "Buscar iconos…",
|
|
3586
|
+
all: "Todos",
|
|
3587
|
+
style: "Estilo",
|
|
3588
|
+
size: "Tamaño",
|
|
3589
|
+
color: "Color",
|
|
3590
|
+
useColor: " Usar color",
|
|
3591
|
+
selectHint: "Seleccionar un icono",
|
|
3592
|
+
insertBtn: "Insertar icono FA",
|
|
3593
|
+
cancelBtn: "Cancelar",
|
|
3594
|
+
close: "Cerrar",
|
|
3595
|
+
categories: {
|
|
3596
|
+
popular: "Popular",
|
|
3597
|
+
interface: "Interfaz",
|
|
3598
|
+
navigation: "Navegación",
|
|
3599
|
+
media: "Medios",
|
|
3600
|
+
communication: "Comunicación",
|
|
3601
|
+
files: "Archivos",
|
|
3602
|
+
people: "Personas",
|
|
3603
|
+
objects: "Objetos"
|
|
3604
|
+
}
|
|
3605
|
+
},
|
|
3606
|
+
findReplace: {
|
|
3607
|
+
findTitle: "Buscar",
|
|
3608
|
+
findReplaceTitle: "Buscar y reemplazar",
|
|
3609
|
+
findPlaceholder: "Buscar…",
|
|
3610
|
+
searchAriaLabel: "Texto de búsqueda",
|
|
3611
|
+
caseSensitive: "\xA0Distinguir mayúsculas",
|
|
3612
|
+
prevBtn: "← Anterior",
|
|
3613
|
+
nextBtn: "Siguiente →",
|
|
3614
|
+
replacePlaceholder: "Reemplazar con…",
|
|
3615
|
+
replaceAriaLabel: "Reemplazar con",
|
|
3616
|
+
replaceBtn: "Reemplazar",
|
|
3617
|
+
replaceAllBtn: "Reemplazar todo",
|
|
3618
|
+
close: "×"
|
|
3619
|
+
},
|
|
3620
|
+
shortcutsDialog: {
|
|
3621
|
+
title: "Atajos de teclado",
|
|
3622
|
+
ariaLabel: "Atajos de teclado",
|
|
3623
|
+
close: "Cerrar",
|
|
3624
|
+
shortcuts: [
|
|
3625
|
+
{
|
|
3626
|
+
category: "Formato de texto",
|
|
3627
|
+
items: [
|
|
3628
|
+
{
|
|
3629
|
+
keys: "Ctrl + B",
|
|
3630
|
+
action: "Negrita"
|
|
3631
|
+
},
|
|
3632
|
+
{
|
|
3633
|
+
keys: "Ctrl + I",
|
|
3634
|
+
action: "Cursiva"
|
|
3635
|
+
},
|
|
3636
|
+
{
|
|
3637
|
+
keys: "Ctrl + U",
|
|
3638
|
+
action: "Subrayado"
|
|
3639
|
+
},
|
|
3640
|
+
{
|
|
3641
|
+
keys: "Ctrl + K",
|
|
3642
|
+
action: "Insertar / editar enlace"
|
|
3643
|
+
}
|
|
3644
|
+
]
|
|
3645
|
+
},
|
|
3646
|
+
{
|
|
3647
|
+
category: "Historial",
|
|
3648
|
+
items: [{
|
|
3649
|
+
keys: "Ctrl + Z",
|
|
3650
|
+
action: "Deshacer"
|
|
3651
|
+
}, {
|
|
3652
|
+
keys: "Ctrl + Y / Ctrl + Shift + Z",
|
|
3653
|
+
action: "Rehacer"
|
|
3654
|
+
}]
|
|
3655
|
+
},
|
|
3656
|
+
{
|
|
3657
|
+
category: "Selección y navegación",
|
|
3658
|
+
items: [
|
|
3659
|
+
{
|
|
3660
|
+
keys: "Ctrl + A",
|
|
3661
|
+
action: "Seleccionar todo"
|
|
3662
|
+
},
|
|
3663
|
+
{
|
|
3664
|
+
keys: "Tab",
|
|
3665
|
+
action: "Aumentar sangría / insertar espacios"
|
|
3666
|
+
},
|
|
3667
|
+
{
|
|
3668
|
+
keys: "Shift + Tab",
|
|
3669
|
+
action: "Reducir sangría"
|
|
3670
|
+
}
|
|
3671
|
+
]
|
|
3672
|
+
},
|
|
3673
|
+
{
|
|
3674
|
+
category: "Portapapeles",
|
|
3675
|
+
items: [{
|
|
3676
|
+
keys: "Ctrl + Shift + V",
|
|
3677
|
+
action: "Pegar como texto plano"
|
|
3678
|
+
}]
|
|
3679
|
+
},
|
|
3680
|
+
{
|
|
3681
|
+
category: "Buscar y reemplazar",
|
|
3682
|
+
items: [{
|
|
3683
|
+
keys: "Ctrl + F",
|
|
3684
|
+
action: "Buscar en el documento"
|
|
3685
|
+
}, {
|
|
3686
|
+
keys: "Ctrl + H",
|
|
3687
|
+
action: "Buscar y reemplazar"
|
|
3688
|
+
}]
|
|
3689
|
+
},
|
|
3690
|
+
{
|
|
3691
|
+
category: "Editor",
|
|
3692
|
+
items: [{
|
|
3693
|
+
keys: "Ctrl + Shift + /",
|
|
3694
|
+
action: "Mostrar este diálogo de atajos"
|
|
3695
|
+
}]
|
|
3696
|
+
}
|
|
3697
|
+
]
|
|
3698
|
+
},
|
|
3699
|
+
contextMenu: {
|
|
3700
|
+
cut: "Cortar",
|
|
3701
|
+
copy: "Copiar",
|
|
3702
|
+
paste: "Pegar",
|
|
3703
|
+
bold: "Negrita",
|
|
3704
|
+
italic: "Cursiva",
|
|
3705
|
+
underline: "Subrayado",
|
|
3706
|
+
textColor: "Color del texto",
|
|
3707
|
+
highlightColor: "Color de resaltado",
|
|
3708
|
+
copyFormat: "Copiar formato",
|
|
3709
|
+
pasteFormat: "Pegar formato",
|
|
3710
|
+
removeFormat: "Eliminar formato",
|
|
3711
|
+
link: "Insertar enlace",
|
|
3712
|
+
image: "Insertar imagen",
|
|
3713
|
+
video: "Insertar vídeo",
|
|
3714
|
+
table: "Insertar tabla",
|
|
3715
|
+
back: "Atrás",
|
|
3716
|
+
noHighlight: "Sin resaltado",
|
|
3717
|
+
customColor: "Color personalizado",
|
|
3718
|
+
customColorLabel: "Personalizado…"
|
|
3719
|
+
},
|
|
3720
|
+
statusbar: {
|
|
3721
|
+
resizeHandle: "Redimensionar editor",
|
|
3722
|
+
words: (n) => `Palabras: ${n}`,
|
|
3723
|
+
wordsLimit: (n, max) => `Palabras: ${n}/${max}`,
|
|
3724
|
+
chars: (n) => `Caracteres: ${n}`,
|
|
3725
|
+
charsLimit: (n, max) => `Caracteres: ${n}/${max}`
|
|
3726
|
+
},
|
|
3727
|
+
tooltips: {
|
|
3728
|
+
link: {
|
|
3729
|
+
ariaLabel: "Acciones de enlace",
|
|
3730
|
+
openLink: "Abrir enlace",
|
|
3731
|
+
copyUrl: "Copiar URL",
|
|
3732
|
+
editLink: "Editar enlace",
|
|
3733
|
+
removeLink: "Eliminar enlace"
|
|
3734
|
+
},
|
|
3735
|
+
image: {
|
|
3736
|
+
ariaLabel: "Acciones de imagen",
|
|
3737
|
+
label: "Imagen",
|
|
3738
|
+
floatLeft: "Flotar a la izquierda",
|
|
3739
|
+
noFloat: "Sin flotado",
|
|
3740
|
+
alignCenter: "Centrar",
|
|
3741
|
+
floatRight: "Flotar a la derecha",
|
|
3742
|
+
originalSize: "Tamaño original",
|
|
3743
|
+
rotateLeft: "Rotar a la izquierda",
|
|
3744
|
+
rotateRight: "Rotar a la derecha",
|
|
3745
|
+
cropImage: "Recortar imagen",
|
|
3746
|
+
addCaption: "Añadir / editar pie de foto",
|
|
3747
|
+
deleteImage: "Eliminar imagen"
|
|
3748
|
+
},
|
|
3749
|
+
code: {
|
|
3750
|
+
ariaLabel: "Acciones de bloque de código",
|
|
3751
|
+
label: "Código",
|
|
3752
|
+
syntaxLanguage: "Lenguaje de sintaxis",
|
|
3753
|
+
syntaxAriaLabel: "Lenguaje de sintaxis",
|
|
3754
|
+
copyCode: "Copiar código",
|
|
3755
|
+
toggleWordWrap: "Alternar ajuste de línea",
|
|
3756
|
+
enableWordWrap: "Activar ajuste de línea",
|
|
3757
|
+
disableWordWrap: "Desactivar ajuste de línea",
|
|
3758
|
+
convertToParagraph: "Convertir en párrafo",
|
|
3759
|
+
deleteCodeBlock: "Eliminar bloque de código"
|
|
3760
|
+
},
|
|
3761
|
+
table: {
|
|
3762
|
+
ariaLabel: "Acciones de tabla",
|
|
3763
|
+
label: "Tabla",
|
|
3764
|
+
selectCells: "Seleccionar celdas",
|
|
3765
|
+
addRowAbove: "Añadir fila encima",
|
|
3766
|
+
addRowBelow: "Añadir fila debajo",
|
|
3767
|
+
deleteRow: "Eliminar fila",
|
|
3768
|
+
addColumnLeft: "Añadir columna a la izquierda",
|
|
3769
|
+
addColumnRight: "Añadir columna a la derecha",
|
|
3770
|
+
deleteColumn: "Eliminar columna",
|
|
3771
|
+
mergeCells: "Combinar celdas",
|
|
3772
|
+
unmergeCells: "Separar celdas",
|
|
3773
|
+
columnWidth: "Ancho de columna",
|
|
3774
|
+
rowHeight: "Alto de fila",
|
|
3775
|
+
tableBorderWidth: "Grosor del borde de la tabla",
|
|
3776
|
+
deleteTable: "Eliminar tabla",
|
|
3777
|
+
columnWidthPx: "Ancho de columna (px)",
|
|
3778
|
+
rowHeightPx: "Alto de fila (px)",
|
|
3779
|
+
tableBorderWidthPx: "Grosor del borde (px)",
|
|
3780
|
+
cancelBtn: "Cancelar",
|
|
3781
|
+
applyBtn: "Aplicar"
|
|
3782
|
+
},
|
|
3783
|
+
video: {
|
|
3784
|
+
ariaLabel: "Acciones de vídeo",
|
|
3785
|
+
label: "Vídeo",
|
|
3786
|
+
floatLeft: "Flotar a la izquierda",
|
|
3787
|
+
noFloat: "Sin flotado",
|
|
3788
|
+
alignCenter: "Centrar",
|
|
3789
|
+
floatRight: "Flotar a la derecha",
|
|
3790
|
+
originalSize: "Tamaño original",
|
|
3791
|
+
previewVideo: "Vista previa de vídeo",
|
|
3792
|
+
exitPreview: "Salir de la vista previa",
|
|
3793
|
+
deleteVideo: "Eliminar vídeo"
|
|
3794
|
+
}
|
|
3795
|
+
},
|
|
3796
|
+
errors: {
|
|
3797
|
+
imageFormat: (type) => `El formato "${type}" no es compatible con los navegadores web. Por favor, conviértalo primero a JPEG, PNG o WebP.`,
|
|
3798
|
+
imageSize: (maxSize) => `El archivo de imagen es demasiado grande. El tamaño máximo permitido es ${maxSize} MB.`
|
|
3799
|
+
}
|
|
3800
|
+
},
|
|
3801
|
+
ko: {
|
|
3802
|
+
toolbar: {
|
|
3803
|
+
bold: "굵게 (Ctrl+B)",
|
|
3804
|
+
italic: "기울임꼴 (Ctrl+I)",
|
|
3805
|
+
underline: "밑줄 (Ctrl+U)",
|
|
3806
|
+
strikethrough: "취소선",
|
|
3807
|
+
superscript: "위 첨자",
|
|
3808
|
+
subscript: "아래 첨자",
|
|
3809
|
+
alignLeft: "왼쪽 정렬",
|
|
3810
|
+
alignCenter: "가운데 정렬",
|
|
3811
|
+
alignRight: "오른쪽 정렬",
|
|
3812
|
+
alignJustify: "양쪽 정렬",
|
|
3813
|
+
ul: "순서 없는 목록",
|
|
3814
|
+
ol: "순서 있는 목록",
|
|
3815
|
+
checklist: "체크리스트",
|
|
3816
|
+
indent: "들여쓰기",
|
|
3817
|
+
outdent: "내어쓰기",
|
|
3818
|
+
undo: "실행 취소 (Ctrl+Z)",
|
|
3819
|
+
redo: "다시 실행 (Ctrl+Y)",
|
|
3820
|
+
hr: "수평선",
|
|
3821
|
+
link: "링크 삽입",
|
|
3822
|
+
image: "이미지 삽입",
|
|
3823
|
+
video: "동영상 삽입",
|
|
3824
|
+
emoji: "이모지 삽입",
|
|
3825
|
+
icon: "FA 아이콘 삽입",
|
|
3826
|
+
table: "표 삽입",
|
|
3827
|
+
fontSize: "글꼴 크기",
|
|
3828
|
+
fontSizePlaceholder: "크기",
|
|
3829
|
+
removeFormat: "서식 제거",
|
|
3830
|
+
direction: "텍스트 방향 전환 (LTR / RTL)",
|
|
3831
|
+
fontFamily: "글꼴",
|
|
3832
|
+
paragraphStyle: "단락 스타일",
|
|
3833
|
+
paragraphStylePlaceholder: "스타일",
|
|
3834
|
+
lineHeight: "줄 간격",
|
|
3835
|
+
lineHeightPlaceholder: "↕ 줄",
|
|
3836
|
+
codeview: "HTML 코드 보기",
|
|
3837
|
+
fullscreen: "전체 화면",
|
|
3838
|
+
shortcuts: "키보드 단축키 (Ctrl+Shift+/)",
|
|
3839
|
+
find: "찾기 (Ctrl+F)",
|
|
3840
|
+
findReplace: "찾기 및 바꾸기 (Ctrl+H)",
|
|
3841
|
+
inlineCode: "인라인 코드 (Ctrl+`)",
|
|
3842
|
+
print: "인쇄",
|
|
3843
|
+
foreColor: "글자 색",
|
|
3844
|
+
backColor: "강조 색",
|
|
3845
|
+
chooseTextColor: "글자 색 선택",
|
|
3846
|
+
chooseHighlightColor: "강조 색 선택",
|
|
3847
|
+
customColor: "사용자 지정 색",
|
|
3848
|
+
insertTableLabel: "표 삽입",
|
|
3849
|
+
paragraphItems: {
|
|
3850
|
+
p: "기본",
|
|
3851
|
+
blockquote: "인용",
|
|
3852
|
+
pre: "코드"
|
|
3853
|
+
}
|
|
3854
|
+
},
|
|
3855
|
+
linkDialog: {
|
|
3856
|
+
ariaLabel: "링크 삽입",
|
|
3857
|
+
title: "링크 삽입",
|
|
3858
|
+
url: "URL",
|
|
3859
|
+
urlPlaceholder: "https://",
|
|
3860
|
+
displayText: "표시 텍스트",
|
|
3861
|
+
textPlaceholder: "링크 텍스트",
|
|
3862
|
+
openInNewTab: "새 탭에서 열기",
|
|
3863
|
+
insertBtn: "삽입",
|
|
3864
|
+
cancelBtn: "취소"
|
|
3865
|
+
},
|
|
3866
|
+
imageDialog: {
|
|
3867
|
+
ariaLabel: "이미지 삽입",
|
|
3868
|
+
title: "이미지 삽입",
|
|
3869
|
+
imageUrl: "이미지 URL",
|
|
3870
|
+
urlPlaceholder: "https://example.com/image.png",
|
|
3871
|
+
altText: "대체 텍스트",
|
|
3872
|
+
altPlaceholder: "이미지 설명",
|
|
3873
|
+
alignment: "정렬",
|
|
3874
|
+
alignNone: "없음",
|
|
3875
|
+
alignLeft: "왼쪽",
|
|
3876
|
+
alignCenter: "가운데",
|
|
3877
|
+
alignRight: "오른쪽",
|
|
3878
|
+
uploadLabel: "또는 파일 업로드",
|
|
3879
|
+
insertBtn: "삽입",
|
|
3880
|
+
cancelBtn: "취소"
|
|
3881
|
+
},
|
|
3882
|
+
videoDialog: {
|
|
3883
|
+
ariaLabel: "동영상 삽입",
|
|
3884
|
+
title: "동영상 삽입",
|
|
3885
|
+
videoUrl: "동영상 URL",
|
|
3886
|
+
urlPlaceholder: "YouTube, Vimeo 또는 직접 .mp4 URL",
|
|
3887
|
+
widthLabel: "너비 (px)",
|
|
3888
|
+
widthPlaceholder: "560",
|
|
3889
|
+
insertBtn: "삽입",
|
|
3890
|
+
cancelBtn: "취소",
|
|
3891
|
+
detected: (type) => `감지됨: ${type}`,
|
|
3892
|
+
unknownFormat: "알 수 없는 형식 — 직접 동영상 임베드를 시도합니다",
|
|
3893
|
+
invalidUrl: "유효하지 않은 URL — 올바른 동영상 링크를 입력하세요."
|
|
3894
|
+
},
|
|
3895
|
+
emojiDialog: {
|
|
3896
|
+
ariaLabel: "이모지 삽입",
|
|
3897
|
+
title: "이모지 삽입",
|
|
3898
|
+
searchPlaceholder: "이모지 검색…",
|
|
3899
|
+
all: "전체",
|
|
3900
|
+
cancelBtn: "취소",
|
|
3901
|
+
close: "닫기",
|
|
3902
|
+
categories: {
|
|
3903
|
+
smileys: "스마일",
|
|
3904
|
+
people: "사람",
|
|
3905
|
+
animals: "동물",
|
|
3906
|
+
food: "음식",
|
|
3907
|
+
travel: "여행",
|
|
3908
|
+
objects: "사물",
|
|
3909
|
+
symbols: "기호"
|
|
3910
|
+
}
|
|
3911
|
+
},
|
|
3912
|
+
iconDialog: {
|
|
3913
|
+
ariaLabel: "FA 아이콘 삽입",
|
|
3914
|
+
title: "FA 아이콘 삽입",
|
|
3915
|
+
searchPlaceholder: "아이콘 검색…",
|
|
3916
|
+
all: "전체",
|
|
3917
|
+
style: "스타일",
|
|
3918
|
+
size: "크기",
|
|
3919
|
+
color: "색상",
|
|
3920
|
+
useColor: " 색상 사용",
|
|
3921
|
+
selectHint: "아이콘을 선택하세요",
|
|
3922
|
+
insertBtn: "FA 아이콘 삽입",
|
|
3923
|
+
cancelBtn: "취소",
|
|
3924
|
+
close: "닫기",
|
|
3925
|
+
categories: {
|
|
3926
|
+
popular: "인기",
|
|
3927
|
+
interface: "인터페이스",
|
|
3928
|
+
navigation: "탐색",
|
|
3929
|
+
media: "미디어",
|
|
3930
|
+
communication: "커뮤니케이션",
|
|
3931
|
+
files: "파일",
|
|
3932
|
+
people: "사람",
|
|
3933
|
+
objects: "사물"
|
|
3934
|
+
}
|
|
3935
|
+
},
|
|
3936
|
+
findReplace: {
|
|
3937
|
+
findTitle: "찾기",
|
|
3938
|
+
findReplaceTitle: "찾기 및 바꾸기",
|
|
3939
|
+
findPlaceholder: "찾기…",
|
|
3940
|
+
searchAriaLabel: "검색 텍스트",
|
|
3941
|
+
caseSensitive: "\xA0대소문자 구분",
|
|
3942
|
+
prevBtn: "← 이전",
|
|
3943
|
+
nextBtn: "다음 →",
|
|
3944
|
+
replacePlaceholder: "바꿀 내용…",
|
|
3945
|
+
replaceAriaLabel: "바꿀 내용",
|
|
3946
|
+
replaceBtn: "바꾸기",
|
|
3947
|
+
replaceAllBtn: "모두 바꾸기",
|
|
3948
|
+
close: "×"
|
|
3949
|
+
},
|
|
3950
|
+
shortcutsDialog: {
|
|
3951
|
+
title: "키보드 단축키",
|
|
3952
|
+
ariaLabel: "키보드 단축키",
|
|
3953
|
+
close: "닫기",
|
|
3954
|
+
shortcuts: [
|
|
3955
|
+
{
|
|
3956
|
+
category: "텍스트 서식",
|
|
3957
|
+
items: [
|
|
3958
|
+
{
|
|
3959
|
+
keys: "Ctrl + B",
|
|
3960
|
+
action: "굵게"
|
|
3961
|
+
},
|
|
3962
|
+
{
|
|
3963
|
+
keys: "Ctrl + I",
|
|
3964
|
+
action: "기울임꼴"
|
|
3965
|
+
},
|
|
3966
|
+
{
|
|
3967
|
+
keys: "Ctrl + U",
|
|
3968
|
+
action: "밑줄"
|
|
3969
|
+
},
|
|
3970
|
+
{
|
|
3971
|
+
keys: "Ctrl + K",
|
|
3972
|
+
action: "링크 삽입 / 편집"
|
|
3973
|
+
}
|
|
3974
|
+
]
|
|
3975
|
+
},
|
|
3976
|
+
{
|
|
3977
|
+
category: "실행 기록",
|
|
3978
|
+
items: [{
|
|
3979
|
+
keys: "Ctrl + Z",
|
|
3980
|
+
action: "실행 취소"
|
|
3981
|
+
}, {
|
|
3982
|
+
keys: "Ctrl + Y / Ctrl + Shift + Z",
|
|
3983
|
+
action: "다시 실행"
|
|
3984
|
+
}]
|
|
3985
|
+
},
|
|
3986
|
+
{
|
|
3987
|
+
category: "선택 및 탐색",
|
|
3988
|
+
items: [
|
|
3989
|
+
{
|
|
3990
|
+
keys: "Ctrl + A",
|
|
3991
|
+
action: "전체 선택"
|
|
3992
|
+
},
|
|
3993
|
+
{
|
|
3994
|
+
keys: "Tab",
|
|
3995
|
+
action: "목록 들여쓰기 / 공백 삽입"
|
|
3996
|
+
},
|
|
3997
|
+
{
|
|
3998
|
+
keys: "Shift + Tab",
|
|
3999
|
+
action: "목록 내어쓰기"
|
|
4000
|
+
}
|
|
4001
|
+
]
|
|
4002
|
+
},
|
|
4003
|
+
{
|
|
4004
|
+
category: "클립보드",
|
|
4005
|
+
items: [{
|
|
4006
|
+
keys: "Ctrl + Shift + V",
|
|
4007
|
+
action: "일반 텍스트로 붙여넣기"
|
|
4008
|
+
}]
|
|
4009
|
+
},
|
|
4010
|
+
{
|
|
4011
|
+
category: "찾기 및 바꾸기",
|
|
4012
|
+
items: [{
|
|
4013
|
+
keys: "Ctrl + F",
|
|
4014
|
+
action: "문서에서 찾기"
|
|
4015
|
+
}, {
|
|
4016
|
+
keys: "Ctrl + H",
|
|
4017
|
+
action: "찾기 및 바꾸기"
|
|
4018
|
+
}]
|
|
4019
|
+
},
|
|
4020
|
+
{
|
|
4021
|
+
category: "편집기",
|
|
4022
|
+
items: [{
|
|
4023
|
+
keys: "Ctrl + Shift + /",
|
|
4024
|
+
action: "이 단축키 대화상자 표시"
|
|
4025
|
+
}]
|
|
4026
|
+
}
|
|
4027
|
+
]
|
|
4028
|
+
},
|
|
4029
|
+
contextMenu: {
|
|
4030
|
+
cut: "잘라내기",
|
|
4031
|
+
copy: "복사",
|
|
4032
|
+
paste: "붙여넣기",
|
|
4033
|
+
bold: "굵게",
|
|
4034
|
+
italic: "기울임꼴",
|
|
4035
|
+
underline: "밑줄",
|
|
4036
|
+
textColor: "글자 색",
|
|
4037
|
+
highlightColor: "강조 색",
|
|
4038
|
+
copyFormat: "서식 복사",
|
|
4039
|
+
pasteFormat: "서식 붙여넣기",
|
|
4040
|
+
removeFormat: "서식 제거",
|
|
4041
|
+
link: "링크 삽입",
|
|
4042
|
+
image: "이미지 삽입",
|
|
4043
|
+
video: "동영상 삽입",
|
|
4044
|
+
table: "표 삽입",
|
|
4045
|
+
back: "뒤로",
|
|
4046
|
+
noHighlight: "강조 없음",
|
|
4047
|
+
customColor: "사용자 지정 색",
|
|
4048
|
+
customColorLabel: "사용자 지정…"
|
|
4049
|
+
},
|
|
4050
|
+
statusbar: {
|
|
4051
|
+
resizeHandle: "편집기 크기 조정",
|
|
4052
|
+
words: (n) => `단어: ${n}`,
|
|
4053
|
+
wordsLimit: (n, max) => `단어: ${n}/${max}`,
|
|
4054
|
+
chars: (n) => `글자: ${n}`,
|
|
4055
|
+
charsLimit: (n, max) => `글자: ${n}/${max}`
|
|
4056
|
+
},
|
|
4057
|
+
tooltips: {
|
|
4058
|
+
link: {
|
|
4059
|
+
ariaLabel: "링크 작업",
|
|
4060
|
+
openLink: "링크 열기",
|
|
4061
|
+
copyUrl: "URL 복사",
|
|
4062
|
+
editLink: "링크 편집",
|
|
4063
|
+
removeLink: "링크 제거"
|
|
4064
|
+
},
|
|
4065
|
+
image: {
|
|
4066
|
+
ariaLabel: "이미지 작업",
|
|
4067
|
+
label: "이미지",
|
|
4068
|
+
floatLeft: "왼쪽 배치",
|
|
4069
|
+
noFloat: "배치 없음",
|
|
4070
|
+
alignCenter: "가운데 정렬",
|
|
4071
|
+
floatRight: "오른쪽 배치",
|
|
4072
|
+
originalSize: "원본 크기",
|
|
4073
|
+
rotateLeft: "왼쪽 회전",
|
|
4074
|
+
rotateRight: "오른쪽 회전",
|
|
4075
|
+
cropImage: "이미지 자르기",
|
|
4076
|
+
addCaption: "캡션 추가 / 편집",
|
|
4077
|
+
deleteImage: "이미지 삭제"
|
|
4078
|
+
},
|
|
4079
|
+
code: {
|
|
4080
|
+
ariaLabel: "코드 블록 작업",
|
|
4081
|
+
label: "코드",
|
|
4082
|
+
syntaxLanguage: "구문 언어",
|
|
4083
|
+
syntaxAriaLabel: "구문 언어",
|
|
4084
|
+
copyCode: "코드 복사",
|
|
4085
|
+
toggleWordWrap: "줄 바꿈 전환",
|
|
4086
|
+
enableWordWrap: "줄 바꿈 사용",
|
|
4087
|
+
disableWordWrap: "줄 바꿈 해제",
|
|
4088
|
+
convertToParagraph: "단락으로 변환",
|
|
4089
|
+
deleteCodeBlock: "코드 블록 삭제"
|
|
4090
|
+
},
|
|
4091
|
+
table: {
|
|
4092
|
+
ariaLabel: "표 작업",
|
|
4093
|
+
label: "표",
|
|
4094
|
+
selectCells: "셀 선택",
|
|
4095
|
+
addRowAbove: "위에 행 추가",
|
|
4096
|
+
addRowBelow: "아래에 행 추가",
|
|
4097
|
+
deleteRow: "행 삭제",
|
|
4098
|
+
addColumnLeft: "왼쪽에 열 추가",
|
|
4099
|
+
addColumnRight: "오른쪽에 열 추가",
|
|
4100
|
+
deleteColumn: "열 삭제",
|
|
4101
|
+
mergeCells: "셀 병합",
|
|
4102
|
+
unmergeCells: "셀 분할",
|
|
4103
|
+
columnWidth: "열 너비",
|
|
4104
|
+
rowHeight: "행 높이",
|
|
4105
|
+
tableBorderWidth: "표 테두리 너비",
|
|
4106
|
+
deleteTable: "표 삭제",
|
|
4107
|
+
columnWidthPx: "열 너비 (px)",
|
|
4108
|
+
rowHeightPx: "행 높이 (px)",
|
|
4109
|
+
tableBorderWidthPx: "표 테두리 너비 (px)",
|
|
4110
|
+
cancelBtn: "취소",
|
|
4111
|
+
applyBtn: "적용"
|
|
4112
|
+
},
|
|
4113
|
+
video: {
|
|
4114
|
+
ariaLabel: "동영상 작업",
|
|
4115
|
+
label: "동영상",
|
|
4116
|
+
floatLeft: "왼쪽 배치",
|
|
4117
|
+
noFloat: "배치 없음",
|
|
4118
|
+
alignCenter: "가운데 정렬",
|
|
4119
|
+
floatRight: "오른쪽 배치",
|
|
4120
|
+
originalSize: "원본 크기",
|
|
4121
|
+
previewVideo: "동영상 미리보기",
|
|
4122
|
+
exitPreview: "미리보기 종료",
|
|
4123
|
+
deleteVideo: "동영상 삭제"
|
|
4124
|
+
}
|
|
4125
|
+
},
|
|
4126
|
+
errors: {
|
|
4127
|
+
imageFormat: (type) => `"${type}" 형식은 웹 브라우저에서 지원되지 않습니다. JPEG, PNG 또는 WebP로 변환해 주세요.`,
|
|
4128
|
+
imageSize: (maxSize) => `이미지 파일이 너무 큽니다. 최대 허용 크기는 ${maxSize} MB입니다.`
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
};
|
|
4132
|
+
/**
|
|
4133
|
+
* Resolve a locale object from a lang option value.
|
|
4134
|
+
*
|
|
4135
|
+
* @param {string | Partial<AsnLocale> | null | undefined} lang
|
|
4136
|
+
* @returns {AsnLocale} A fully-populated locale (always contains every key from en.js).
|
|
4137
|
+
*/
|
|
4138
|
+
function resolveLocale(lang) {
|
|
4139
|
+
if (!lang || lang === "en") return en;
|
|
4140
|
+
if (typeof lang === "string") {
|
|
4141
|
+
const partial = locales[lang];
|
|
4142
|
+
if (!partial) return en;
|
|
4143
|
+
return mergeDeep(mergeDeep({}, en), partial);
|
|
4144
|
+
}
|
|
4145
|
+
if (typeof lang === "object") return mergeDeep(mergeDeep({}, en), lang);
|
|
4146
|
+
return en;
|
|
4147
|
+
}
|
|
4148
|
+
/**
|
|
4149
|
+
* @typedef {Object} AsnLocale (see types/index.d.ts for the full definition)
|
|
4150
|
+
*/
|
|
4151
|
+
//#endregion
|
|
1449
4152
|
//#region src/js/core/sanitise.js
|
|
1450
4153
|
/**
|
|
1451
4154
|
* sanitise.js - Shared HTML and URL sanitisation utilities
|
|
@@ -2965,8 +5668,8 @@ var Editor = class {
|
|
|
2965
5668
|
* Inspired by Summernote's Toolbar module — rewritten without jQuery
|
|
2966
5669
|
*/
|
|
2967
5670
|
var _faPageLevelReady = null;
|
|
2968
|
-
var _S = "stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"";
|
|
2969
|
-
var _svgWrap = (paths) => `<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" ${_S} style="display:block">${paths}</svg>`;
|
|
5671
|
+
var _S$1 = "stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"";
|
|
5672
|
+
var _svgWrap = (paths) => `<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" ${_S$1} style="display:block">${paths}</svg>`;
|
|
2970
5673
|
var _SVG_MAP = new Map([
|
|
2971
5674
|
["bold", _svgWrap("<path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/>")],
|
|
2972
5675
|
["italic", _svgWrap("<line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/>")],
|
|
@@ -3096,9 +5799,9 @@ var Toolbar = class {
|
|
|
3096
5799
|
const btn = createElement("button", {
|
|
3097
5800
|
type: "button",
|
|
3098
5801
|
class: !!this.options.useBootstrap ? this.options.toolbarButtonClass || "btn btn-sm btn-light" : "an-btn",
|
|
3099
|
-
title: def.tooltip || "",
|
|
5802
|
+
title: this.context.locale.toolbar[def.name] || def.tooltip || "",
|
|
3100
5803
|
"data-btn": def.name,
|
|
3101
|
-
"aria-label": def.tooltip || def.name,
|
|
5804
|
+
"aria-label": this.context.locale.toolbar[def.name] || def.tooltip || def.name,
|
|
3102
5805
|
"aria-haspopup": "true",
|
|
3103
5806
|
"aria-expanded": "false"
|
|
3104
5807
|
});
|
|
@@ -3111,7 +5814,7 @@ var Toolbar = class {
|
|
|
3111
5814
|
});
|
|
3112
5815
|
const grid = createElement("div", { class: "an-table-grid" });
|
|
3113
5816
|
const label = createElement("div", { class: "an-table-label" });
|
|
3114
|
-
label.textContent = "Insert Table";
|
|
5817
|
+
label.textContent = this.context.locale.toolbar.insertTableLabel || "Insert Table";
|
|
3115
5818
|
const cells = [];
|
|
3116
5819
|
for (let r = 1; r <= ROWS; r++) for (let c = 1; c <= COLS; c++) {
|
|
3117
5820
|
const cell = createElement("div", {
|
|
@@ -3131,7 +5834,7 @@ var Toolbar = class {
|
|
|
3131
5834
|
const c = +cell.getAttribute("data-col");
|
|
3132
5835
|
cell.classList.toggle("active", r <= rows && c <= cols);
|
|
3133
5836
|
});
|
|
3134
|
-
label.textContent = rows && cols ? `${rows} × ${cols}` : "Insert Table";
|
|
5837
|
+
label.textContent = rows && cols ? `${rows} × ${cols}` : this.context.locale.toolbar.insertTableLabel || "Insert Table";
|
|
3135
5838
|
};
|
|
3136
5839
|
const openPopup = () => {
|
|
3137
5840
|
isOpen = true;
|
|
@@ -3211,9 +5914,9 @@ var Toolbar = class {
|
|
|
3211
5914
|
const applyBtn = createElement("button", {
|
|
3212
5915
|
type: "button",
|
|
3213
5916
|
class: `${baseClass} an-color-btn`,
|
|
3214
|
-
title: def.tooltip || "",
|
|
5917
|
+
title: this.context.locale.toolbar[def.name] || def.tooltip || "",
|
|
3215
5918
|
"data-btn": def.name,
|
|
3216
|
-
"aria-label": def.tooltip || def.name
|
|
5919
|
+
"aria-label": this.context.locale.toolbar[def.name] || def.tooltip || def.name
|
|
3217
5920
|
});
|
|
3218
5921
|
const S = "stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"";
|
|
3219
5922
|
applyBtn.innerHTML = def.name === "foreColor" ? `<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" ${S} style="display:block"><path d="M4 20L12 4L20 20"/><line x1="7.5" y1="14" x2="16.5" y2="14"/></svg>` : `<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" ${S} style="display:block"><path d="M3 21v-4l9-9 4 4-9 9z"/><path d="M12 8l4 4"/></svg>`;
|
|
@@ -3223,7 +5926,7 @@ var Toolbar = class {
|
|
|
3223
5926
|
const arrowBtn = createElement("button", {
|
|
3224
5927
|
type: "button",
|
|
3225
5928
|
class: `${baseClass} an-color-arrow`,
|
|
3226
|
-
title:
|
|
5929
|
+
title: def.name === "foreColor" ? this.context.locale.toolbar.chooseTextColor || "Choose text color" : this.context.locale.toolbar.chooseHighlightColor || "Choose highlight color",
|
|
3227
5930
|
"aria-haspopup": "true",
|
|
3228
5931
|
"aria-expanded": "false"
|
|
3229
5932
|
});
|
|
@@ -3245,9 +5948,9 @@ var Toolbar = class {
|
|
|
3245
5948
|
const colorInput = createElement("input", {
|
|
3246
5949
|
type: "color",
|
|
3247
5950
|
value: currentColor,
|
|
3248
|
-
title: "Custom color"
|
|
5951
|
+
title: this.context.locale.toolbar.customColor || "Custom color"
|
|
3249
5952
|
});
|
|
3250
|
-
const customLabel = createElement("span", {}, ["Custom color"]);
|
|
5953
|
+
const customLabel = createElement("span", {}, [this.context.locale.toolbar.customColor || "Custom color"]);
|
|
3251
5954
|
customRow.appendChild(colorInput);
|
|
3252
5955
|
customRow.appendChild(customLabel);
|
|
3253
5956
|
popup.appendChild(swatches);
|
|
@@ -3357,19 +6060,19 @@ var Toolbar = class {
|
|
|
3357
6060
|
const items = def.name === "fontFamily" ? this.options.fontFamilies || [] : def.items || [];
|
|
3358
6061
|
const select = createElement("select", {
|
|
3359
6062
|
class: def.selectClass ? `an-select ${def.selectClass}` : "an-select",
|
|
3360
|
-
title: def.tooltip || "",
|
|
6063
|
+
title: this.context.locale.toolbar[def.name] || def.tooltip || "",
|
|
3361
6064
|
"data-btn": def.name,
|
|
3362
|
-
"aria-label": def.tooltip || def.name
|
|
6065
|
+
"aria-label": this.context.locale.toolbar[def.name] || def.tooltip || def.name
|
|
3363
6066
|
});
|
|
3364
6067
|
const placeholder = createElement("option", {
|
|
3365
6068
|
value: "",
|
|
3366
6069
|
disabled: "",
|
|
3367
6070
|
hidden: ""
|
|
3368
|
-
}, [def.placeholder || "Font"]);
|
|
6071
|
+
}, [this.context.locale.toolbar[def.name + "Placeholder"] || def.placeholder || "Font"]);
|
|
3369
6072
|
select.appendChild(placeholder);
|
|
3370
6073
|
items.forEach((item) => {
|
|
3371
6074
|
const value = typeof item === "object" ? item.value : item;
|
|
3372
|
-
const label = typeof item === "object" ? item.label : item;
|
|
6075
|
+
const label = typeof item === "object" ? def.name === "paragraphStyle" ? (this.context.locale.toolbar.paragraphItems || {})[item.value] || item.label : item.label : item;
|
|
3373
6076
|
const isHeader = typeof item === "object" && !!item.disabled;
|
|
3374
6077
|
const attrs = { value };
|
|
3375
6078
|
if (isHeader) attrs.disabled = "";
|
|
@@ -3409,9 +6112,9 @@ var Toolbar = class {
|
|
|
3409
6112
|
const btn = createElement("button", {
|
|
3410
6113
|
type: "button",
|
|
3411
6114
|
class: `${!!this.options.useBootstrap ? this.options.toolbarButtonClass || "btn btn-sm btn-light" : `an-btn`}${btnDef.className ? ` ${btnDef.className}` : ""}`,
|
|
3412
|
-
title: btnDef.tooltip || "",
|
|
6115
|
+
title: this.context.locale.toolbar[btnDef.name] || btnDef.tooltip || "",
|
|
3413
6116
|
"data-btn": btnDef.name,
|
|
3414
|
-
"aria-label": btnDef.tooltip || btnDef.name
|
|
6117
|
+
"aria-label": this.context.locale.toolbar[btnDef.name] || btnDef.tooltip || btnDef.name
|
|
3415
6118
|
});
|
|
3416
6119
|
const faPrefix = this.options.fontAwesomeClass || "fas";
|
|
3417
6120
|
if (this._faReady) {
|
|
@@ -3536,7 +6239,7 @@ var Statusbar = class {
|
|
|
3536
6239
|
if (this.options.resizable !== false) {
|
|
3537
6240
|
const handle = createElement("div", {
|
|
3538
6241
|
class: "an-resize-handle",
|
|
3539
|
-
title:
|
|
6242
|
+
title: this.context.locale.statusbar.resizeHandle,
|
|
3540
6243
|
"aria-hidden": "true"
|
|
3541
6244
|
});
|
|
3542
6245
|
this._bindResize(handle);
|
|
@@ -3626,8 +6329,9 @@ var Statusbar = class {
|
|
|
3626
6329
|
const chars = text.replace(/\n/g, "").length;
|
|
3627
6330
|
const maxWords = this.options.maxWords || 0;
|
|
3628
6331
|
const maxChars = this.options.maxChars || 0;
|
|
3629
|
-
this.
|
|
3630
|
-
this.
|
|
6332
|
+
const LS = this.context.locale.statusbar;
|
|
6333
|
+
this._wordCountEl.textContent = maxWords ? LS.wordsLimit(words, maxWords) : LS.words(words);
|
|
6334
|
+
this._charCountEl.textContent = maxChars ? LS.charsLimit(chars, maxChars) : LS.chars(chars);
|
|
3631
6335
|
_applyLimitClass(this._wordCountEl, words, maxWords);
|
|
3632
6336
|
_applyLimitClass(this._charCountEl, chars, maxChars);
|
|
3633
6337
|
}
|
|
@@ -4224,32 +6928,33 @@ var LinkDialog = class {
|
|
|
4224
6928
|
this._open();
|
|
4225
6929
|
}
|
|
4226
6930
|
_buildDialog() {
|
|
6931
|
+
const L = this.context.locale.linkDialog;
|
|
4227
6932
|
const overlay = createElement("div", {
|
|
4228
6933
|
class: "an-dialog-overlay",
|
|
4229
6934
|
role: "dialog",
|
|
4230
6935
|
"aria-modal": "true",
|
|
4231
|
-
"aria-label":
|
|
6936
|
+
"aria-label": L.ariaLabel
|
|
4232
6937
|
});
|
|
4233
6938
|
const box = createElement("div", { class: "an-dialog-box" });
|
|
4234
6939
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
4235
|
-
title.textContent =
|
|
6940
|
+
title.textContent = L.title;
|
|
4236
6941
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
4237
|
-
urlLabel.textContent =
|
|
6942
|
+
urlLabel.textContent = L.url;
|
|
4238
6943
|
const urlInput = createElement("input", {
|
|
4239
6944
|
type: "url",
|
|
4240
6945
|
class: "an-input",
|
|
4241
|
-
placeholder:
|
|
6946
|
+
placeholder: L.urlPlaceholder,
|
|
4242
6947
|
id: "an-link-url",
|
|
4243
6948
|
name: "url",
|
|
4244
6949
|
autocomplete: "off"
|
|
4245
6950
|
});
|
|
4246
6951
|
this._urlInput = urlInput;
|
|
4247
6952
|
const textLabel = createElement("label", { class: "an-label" });
|
|
4248
|
-
textLabel.textContent =
|
|
6953
|
+
textLabel.textContent = L.displayText;
|
|
4249
6954
|
const textInput = createElement("input", {
|
|
4250
6955
|
type: "text",
|
|
4251
6956
|
class: "an-input",
|
|
4252
|
-
placeholder:
|
|
6957
|
+
placeholder: L.textPlaceholder,
|
|
4253
6958
|
id: "an-link-text",
|
|
4254
6959
|
name: "linkText",
|
|
4255
6960
|
autocomplete: "off"
|
|
@@ -4263,18 +6968,18 @@ var LinkDialog = class {
|
|
|
4263
6968
|
});
|
|
4264
6969
|
this._tabCheckbox = tabCheckbox;
|
|
4265
6970
|
tabLabel.appendChild(tabCheckbox);
|
|
4266
|
-
tabLabel.appendChild(document.createTextNode("
|
|
6971
|
+
tabLabel.appendChild(document.createTextNode(" " + L.openInNewTab));
|
|
4267
6972
|
const btnRow = createElement("div", { class: "an-dialog-actions" });
|
|
4268
6973
|
const insertBtn = createElement("button", {
|
|
4269
6974
|
type: "button",
|
|
4270
6975
|
class: "an-btn an-btn-primary"
|
|
4271
6976
|
});
|
|
4272
|
-
insertBtn.textContent =
|
|
6977
|
+
insertBtn.textContent = L.insertBtn;
|
|
4273
6978
|
const cancelBtn = createElement("button", {
|
|
4274
6979
|
type: "button",
|
|
4275
6980
|
class: "an-btn"
|
|
4276
6981
|
});
|
|
4277
|
-
cancelBtn.textContent =
|
|
6982
|
+
cancelBtn.textContent = L.cancelBtn;
|
|
4278
6983
|
btnRow.appendChild(insertBtn);
|
|
4279
6984
|
btnRow.appendChild(cancelBtn);
|
|
4280
6985
|
box.append(title, urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);
|
|
@@ -4400,53 +7105,54 @@ var ImageDialog = class {
|
|
|
4400
7105
|
this._open();
|
|
4401
7106
|
}
|
|
4402
7107
|
_buildDialog() {
|
|
7108
|
+
const L = this.context.locale.imageDialog;
|
|
4403
7109
|
const overlay = createElement("div", {
|
|
4404
7110
|
class: "an-dialog-overlay",
|
|
4405
7111
|
role: "dialog",
|
|
4406
7112
|
"aria-modal": "true",
|
|
4407
|
-
"aria-label":
|
|
7113
|
+
"aria-label": L.ariaLabel
|
|
4408
7114
|
});
|
|
4409
7115
|
const box = createElement("div", { class: "an-dialog-box" });
|
|
4410
7116
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
4411
|
-
title.textContent =
|
|
7117
|
+
title.textContent = L.title;
|
|
4412
7118
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
4413
|
-
urlLabel.textContent =
|
|
7119
|
+
urlLabel.textContent = L.imageUrl;
|
|
4414
7120
|
const urlInput = createElement("input", {
|
|
4415
7121
|
type: "url",
|
|
4416
7122
|
class: "an-input",
|
|
4417
|
-
placeholder:
|
|
7123
|
+
placeholder: L.urlPlaceholder,
|
|
4418
7124
|
autocomplete: "off"
|
|
4419
7125
|
});
|
|
4420
7126
|
this._urlInput = urlInput;
|
|
4421
7127
|
const altLabel = createElement("label", { class: "an-label" });
|
|
4422
|
-
altLabel.textContent =
|
|
7128
|
+
altLabel.textContent = L.altText;
|
|
4423
7129
|
const altInput = createElement("input", {
|
|
4424
7130
|
type: "text",
|
|
4425
7131
|
class: "an-input",
|
|
4426
|
-
placeholder:
|
|
7132
|
+
placeholder: L.altPlaceholder,
|
|
4427
7133
|
autocomplete: "off"
|
|
4428
7134
|
});
|
|
4429
7135
|
this._altInput = altInput;
|
|
4430
7136
|
box.append(title, urlLabel, urlInput, altLabel, altInput);
|
|
4431
7137
|
const alignLabel = createElement("label", { class: "an-label" });
|
|
4432
|
-
alignLabel.textContent =
|
|
7138
|
+
alignLabel.textContent = L.alignment;
|
|
4433
7139
|
const alignRow = createElement("div", { class: "an-align-row" });
|
|
4434
7140
|
[
|
|
4435
7141
|
{
|
|
4436
7142
|
value: "",
|
|
4437
|
-
label:
|
|
7143
|
+
label: L.alignNone
|
|
4438
7144
|
},
|
|
4439
7145
|
{
|
|
4440
7146
|
value: "left",
|
|
4441
|
-
label:
|
|
7147
|
+
label: L.alignLeft
|
|
4442
7148
|
},
|
|
4443
7149
|
{
|
|
4444
7150
|
value: "center",
|
|
4445
|
-
label:
|
|
7151
|
+
label: L.alignCenter
|
|
4446
7152
|
},
|
|
4447
7153
|
{
|
|
4448
7154
|
value: "right",
|
|
4449
|
-
label:
|
|
7155
|
+
label: L.alignRight
|
|
4450
7156
|
}
|
|
4451
7157
|
].forEach(({ value, label }) => {
|
|
4452
7158
|
const radioId = `an-align-${value || "none"}`;
|
|
@@ -4468,7 +7174,7 @@ var ImageDialog = class {
|
|
|
4468
7174
|
box.append(alignLabel, alignRow);
|
|
4469
7175
|
if (this.options.allowImageUpload !== false) {
|
|
4470
7176
|
const fileLabel = createElement("label", { class: "an-label" });
|
|
4471
|
-
fileLabel.textContent =
|
|
7177
|
+
fileLabel.textContent = L.uploadLabel;
|
|
4472
7178
|
const fileInput = createElement("input", {
|
|
4473
7179
|
type: "file",
|
|
4474
7180
|
class: "an-input",
|
|
@@ -4486,12 +7192,12 @@ var ImageDialog = class {
|
|
|
4486
7192
|
type: "button",
|
|
4487
7193
|
class: "an-btn an-btn-primary"
|
|
4488
7194
|
});
|
|
4489
|
-
insertBtn.textContent =
|
|
7195
|
+
insertBtn.textContent = L.insertBtn;
|
|
4490
7196
|
const cancelBtn = createElement("button", {
|
|
4491
7197
|
type: "button",
|
|
4492
7198
|
class: "an-btn"
|
|
4493
7199
|
});
|
|
4494
|
-
cancelBtn.textContent =
|
|
7200
|
+
cancelBtn.textContent = L.cancelBtn;
|
|
4495
7201
|
btnRow.appendChild(insertBtn);
|
|
4496
7202
|
btnRow.appendChild(cancelBtn);
|
|
4497
7203
|
box.append(btnRow);
|
|
@@ -4527,7 +7233,7 @@ var ImageDialog = class {
|
|
|
4527
7233
|
"image/svg+xml",
|
|
4528
7234
|
"image/avif"
|
|
4529
7235
|
]).has(file.type)) {
|
|
4530
|
-
const message =
|
|
7236
|
+
const message = this.context.locale.errors.imageFormat(file.type);
|
|
4531
7237
|
if (this._fileHint) this._fileHint.textContent = message;
|
|
4532
7238
|
this.context.triggerEvent("imageError", {
|
|
4533
7239
|
file,
|
|
@@ -4539,7 +7245,7 @@ var ImageDialog = class {
|
|
|
4539
7245
|
if (this._fileHint) this._fileHint.textContent = "";
|
|
4540
7246
|
const maxSize = (this.options.maxImageSize || 5) * 1024 * 1024;
|
|
4541
7247
|
if (file.size > maxSize) {
|
|
4542
|
-
const message =
|
|
7248
|
+
const message = this.context.locale.errors.imageSize(this.options.maxImageSize || 5);
|
|
4543
7249
|
if (this._fileHint) this._fileHint.textContent = message;
|
|
4544
7250
|
console.warn("[AutumnNote] ImageDialog:", message);
|
|
4545
7251
|
this.context.triggerEvent("imageError", {
|
|
@@ -4625,28 +7331,29 @@ var VideoDialog = class {
|
|
|
4625
7331
|
this._open();
|
|
4626
7332
|
}
|
|
4627
7333
|
_buildDialog() {
|
|
7334
|
+
const L = this.context.locale.videoDialog;
|
|
4628
7335
|
const overlay = createElement("div", {
|
|
4629
7336
|
class: "an-dialog-overlay",
|
|
4630
7337
|
role: "dialog",
|
|
4631
7338
|
"aria-modal": "true",
|
|
4632
|
-
"aria-label":
|
|
7339
|
+
"aria-label": L.ariaLabel
|
|
4633
7340
|
});
|
|
4634
7341
|
const box = createElement("div", { class: "an-dialog-box" });
|
|
4635
7342
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
4636
|
-
title.textContent =
|
|
7343
|
+
title.textContent = L.title;
|
|
4637
7344
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
4638
|
-
urlLabel.textContent =
|
|
7345
|
+
urlLabel.textContent = L.videoUrl;
|
|
4639
7346
|
const urlInput = createElement("input", {
|
|
4640
7347
|
type: "url",
|
|
4641
7348
|
class: "an-input",
|
|
4642
|
-
placeholder:
|
|
7349
|
+
placeholder: L.urlPlaceholder,
|
|
4643
7350
|
autocomplete: "off"
|
|
4644
7351
|
});
|
|
4645
7352
|
this._urlInput = urlInput;
|
|
4646
7353
|
const hintEl = createElement("p", { class: "an-dialog-hint" });
|
|
4647
7354
|
this._hintEl = hintEl;
|
|
4648
7355
|
const widthLabel = createElement("label", { class: "an-label" });
|
|
4649
|
-
widthLabel.textContent =
|
|
7356
|
+
widthLabel.textContent = L.widthLabel;
|
|
4650
7357
|
const widthInput = createElement("input", {
|
|
4651
7358
|
type: "number",
|
|
4652
7359
|
class: "an-input",
|
|
@@ -4661,19 +7368,19 @@ var VideoDialog = class {
|
|
|
4661
7368
|
type: "button",
|
|
4662
7369
|
class: "an-btn an-btn-primary"
|
|
4663
7370
|
});
|
|
4664
|
-
insertBtn.textContent =
|
|
7371
|
+
insertBtn.textContent = L.insertBtn;
|
|
4665
7372
|
const cancelBtn = createElement("button", {
|
|
4666
7373
|
type: "button",
|
|
4667
7374
|
class: "an-btn"
|
|
4668
7375
|
});
|
|
4669
|
-
cancelBtn.textContent =
|
|
7376
|
+
cancelBtn.textContent = L.cancelBtn;
|
|
4670
7377
|
btnRow.appendChild(insertBtn);
|
|
4671
7378
|
btnRow.appendChild(cancelBtn);
|
|
4672
7379
|
box.append(title, urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);
|
|
4673
7380
|
overlay.appendChild(box);
|
|
4674
7381
|
const d0 = on(urlInput, "input", () => {
|
|
4675
7382
|
const info = this._parseVideoUrl(urlInput.value.trim());
|
|
4676
|
-
hintEl.textContent = info ?
|
|
7383
|
+
hintEl.textContent = info ? this.context.locale.videoDialog.detected(info.type) : urlInput.value ? this.context.locale.videoDialog.unknownFormat : "";
|
|
4677
7384
|
});
|
|
4678
7385
|
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
4679
7386
|
const d2 = on(cancelBtn, "click", () => this._close());
|
|
@@ -4698,7 +7405,7 @@ var VideoDialog = class {
|
|
|
4698
7405
|
}
|
|
4699
7406
|
const html = this._buildEmbedHtml(rawUrl, width);
|
|
4700
7407
|
if (!html) {
|
|
4701
|
-
this._hintEl.textContent =
|
|
7408
|
+
this._hintEl.textContent = this.context.locale.videoDialog.invalidUrl;
|
|
4702
7409
|
this._urlInput.focus();
|
|
4703
7410
|
return;
|
|
4704
7411
|
}
|
|
@@ -5270,19 +7977,20 @@ var LinkTooltip = class {
|
|
|
5270
7977
|
this._el = null;
|
|
5271
7978
|
}
|
|
5272
7979
|
_buildTooltip() {
|
|
7980
|
+
const L = this.context.locale.tooltips.link;
|
|
5273
7981
|
const el = createElement("div", {
|
|
5274
7982
|
class: "an-link-tooltip",
|
|
5275
7983
|
role: "toolbar",
|
|
5276
|
-
"aria-label":
|
|
7984
|
+
"aria-label": L.ariaLabel
|
|
5277
7985
|
});
|
|
5278
7986
|
el.style.display = "none";
|
|
5279
7987
|
this._urlLabel = createElement("span", { class: "an-link-tooltip-url" });
|
|
5280
7988
|
el.appendChild(this._urlLabel);
|
|
5281
7989
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5282
|
-
this._openBtn = this._makeBtn(ICONS$5.open,
|
|
5283
|
-
this._copyBtn = this._makeBtn(ICONS$5.copy,
|
|
5284
|
-
this._editBtn = this._makeBtn(ICONS$5.edit,
|
|
5285
|
-
this._unlinkBtn = this._makeBtn(ICONS$5.unlink,
|
|
7990
|
+
this._openBtn = this._makeBtn(ICONS$5.open, L.openLink, () => this._openLink());
|
|
7991
|
+
this._copyBtn = this._makeBtn(ICONS$5.copy, L.copyUrl, () => this._copyLink());
|
|
7992
|
+
this._editBtn = this._makeBtn(ICONS$5.edit, L.editLink, () => this._editLink());
|
|
7993
|
+
this._unlinkBtn = this._makeBtn(ICONS$5.unlink, L.removeLink, () => this._unlink());
|
|
5286
7994
|
el.appendChild(this._openBtn);
|
|
5287
7995
|
el.appendChild(this._copyBtn);
|
|
5288
7996
|
el.appendChild(this._editBtn);
|
|
@@ -5461,38 +8169,39 @@ var ImageTooltip = class {
|
|
|
5461
8169
|
this._el = null;
|
|
5462
8170
|
}
|
|
5463
8171
|
_buildTooltip() {
|
|
8172
|
+
const L = this.context.locale.tooltips.image;
|
|
5464
8173
|
const el = createElement("div", {
|
|
5465
8174
|
class: "an-link-tooltip an-image-tooltip",
|
|
5466
8175
|
role: "toolbar",
|
|
5467
|
-
"aria-label":
|
|
8176
|
+
"aria-label": L.ariaLabel
|
|
5468
8177
|
});
|
|
5469
8178
|
el.style.display = "none";
|
|
5470
8179
|
this._label = createElement("span", { class: "an-link-tooltip-url" });
|
|
5471
|
-
this._label.textContent =
|
|
8180
|
+
this._label.textContent = L.label;
|
|
5472
8181
|
el.appendChild(this._label);
|
|
5473
8182
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5474
|
-
this._floatLeftBtn = this._makeBtn(ICONS$4.floatLeft,
|
|
5475
|
-
this._floatNoneBtn = this._makeBtn(ICONS$4.floatNone,
|
|
5476
|
-
this._alignCenterBtn = this._makeBtn(ICONS$4.alignCenter,
|
|
5477
|
-
this._floatRightBtn = this._makeBtn(ICONS$4.floatRight,
|
|
8183
|
+
this._floatLeftBtn = this._makeBtn(ICONS$4.floatLeft, L.floatLeft, () => this._setFloat("left"));
|
|
8184
|
+
this._floatNoneBtn = this._makeBtn(ICONS$4.floatNone, L.noFloat, () => this._setFloat(""));
|
|
8185
|
+
this._alignCenterBtn = this._makeBtn(ICONS$4.alignCenter, L.alignCenter, () => this._setCenter());
|
|
8186
|
+
this._floatRightBtn = this._makeBtn(ICONS$4.floatRight, L.floatRight, () => this._setFloat("right"));
|
|
5478
8187
|
el.appendChild(this._floatLeftBtn);
|
|
5479
8188
|
el.appendChild(this._floatNoneBtn);
|
|
5480
8189
|
el.appendChild(this._alignCenterBtn);
|
|
5481
8190
|
el.appendChild(this._floatRightBtn);
|
|
5482
8191
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5483
|
-
this._originalBtn = this._makeBtn(ICONS$4.originalSize,
|
|
8192
|
+
this._originalBtn = this._makeBtn(ICONS$4.originalSize, L.originalSize, () => this._resetSize());
|
|
5484
8193
|
el.appendChild(this._originalBtn);
|
|
5485
8194
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5486
|
-
el.appendChild(this._makeBtn(ICONS$4.rotateLeft,
|
|
5487
|
-
el.appendChild(this._makeBtn(ICONS$4.rotateRight,
|
|
8195
|
+
el.appendChild(this._makeBtn(ICONS$4.rotateLeft, L.rotateLeft, () => this._rotate(-90)));
|
|
8196
|
+
el.appendChild(this._makeBtn(ICONS$4.rotateRight, L.rotateRight, () => this._rotate(90)));
|
|
5488
8197
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5489
|
-
this._cropBtn = this._makeBtn(ICONS$4.crop,
|
|
8198
|
+
this._cropBtn = this._makeBtn(ICONS$4.crop, L.cropImage, () => this._crop());
|
|
5490
8199
|
el.appendChild(this._cropBtn);
|
|
5491
8200
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5492
|
-
this._captionBtn = this._makeBtn(ICONS$4.caption,
|
|
8201
|
+
this._captionBtn = this._makeBtn(ICONS$4.caption, L.addCaption, () => this._toggleCaption());
|
|
5493
8202
|
el.appendChild(this._captionBtn);
|
|
5494
8203
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5495
|
-
this._deleteBtn = this._makeBtn(ICONS$4.deleteImg,
|
|
8204
|
+
this._deleteBtn = this._makeBtn(ICONS$4.deleteImg, L.deleteImage, () => this._delete(), true);
|
|
5496
8205
|
el.appendChild(this._deleteBtn);
|
|
5497
8206
|
this._disposers.push(on(el, "mouseenter", () => this._clearTimers()), on(el, "mouseleave", () => this._scheduleHide()));
|
|
5498
8207
|
return el;
|
|
@@ -5744,32 +8453,33 @@ var VideoTooltip = class {
|
|
|
5744
8453
|
this._el = null;
|
|
5745
8454
|
}
|
|
5746
8455
|
_buildTooltip() {
|
|
8456
|
+
const L = this.context.locale.tooltips.video;
|
|
5747
8457
|
const el = createElement("div", {
|
|
5748
8458
|
class: "an-link-tooltip an-video-tooltip",
|
|
5749
8459
|
role: "toolbar",
|
|
5750
|
-
"aria-label":
|
|
8460
|
+
"aria-label": L.ariaLabel
|
|
5751
8461
|
});
|
|
5752
8462
|
el.style.display = "none";
|
|
5753
8463
|
this._label = createElement("span", { class: "an-link-tooltip-url" });
|
|
5754
|
-
this._label.textContent =
|
|
8464
|
+
this._label.textContent = L.label;
|
|
5755
8465
|
el.appendChild(this._label);
|
|
5756
8466
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5757
|
-
this._floatLeftBtn = this._makeBtn(ICONS$3.floatLeft,
|
|
5758
|
-
this._floatNoneBtn = this._makeBtn(ICONS$3.floatNone,
|
|
5759
|
-
this._alignCenterBtn = this._makeBtn(ICONS$3.alignCenter,
|
|
5760
|
-
this._floatRightBtn = this._makeBtn(ICONS$3.floatRight,
|
|
8467
|
+
this._floatLeftBtn = this._makeBtn(ICONS$3.floatLeft, L.floatLeft, () => this._setFloat("left"));
|
|
8468
|
+
this._floatNoneBtn = this._makeBtn(ICONS$3.floatNone, L.noFloat, () => this._setFloat(""));
|
|
8469
|
+
this._alignCenterBtn = this._makeBtn(ICONS$3.alignCenter, L.alignCenter, () => this._setCenter());
|
|
8470
|
+
this._floatRightBtn = this._makeBtn(ICONS$3.floatRight, L.floatRight, () => this._setFloat("right"));
|
|
5761
8471
|
el.appendChild(this._floatLeftBtn);
|
|
5762
8472
|
el.appendChild(this._floatNoneBtn);
|
|
5763
8473
|
el.appendChild(this._alignCenterBtn);
|
|
5764
8474
|
el.appendChild(this._floatRightBtn);
|
|
5765
8475
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5766
|
-
this._originalBtn = this._makeBtn(ICONS$3.originalSize,
|
|
8476
|
+
this._originalBtn = this._makeBtn(ICONS$3.originalSize, L.originalSize, () => this._resetSize());
|
|
5767
8477
|
el.appendChild(this._originalBtn);
|
|
5768
8478
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5769
|
-
this._previewBtn = this._makeBtn(ICONS$3.preview,
|
|
8479
|
+
this._previewBtn = this._makeBtn(ICONS$3.preview, L.previewVideo, () => this._togglePreview());
|
|
5770
8480
|
el.appendChild(this._previewBtn);
|
|
5771
8481
|
el.appendChild(createElement("div", { class: "an-link-tooltip-sep" }));
|
|
5772
|
-
this._deleteBtn = this._makeBtn(ICONS$3.deleteVideo,
|
|
8482
|
+
this._deleteBtn = this._makeBtn(ICONS$3.deleteVideo, L.deleteVideo, () => this._delete(), true);
|
|
5773
8483
|
el.appendChild(this._deleteBtn);
|
|
5774
8484
|
this._disposers.push(on(el, "mouseenter", () => this._clearTimers()), on(el, "mouseleave", () => this._scheduleHide()));
|
|
5775
8485
|
return el;
|
|
@@ -5906,7 +8616,7 @@ var VideoTooltip = class {
|
|
|
5906
8616
|
if (shield) shield.style.display = "none";
|
|
5907
8617
|
this.context.invoke("videoResizer.deselect");
|
|
5908
8618
|
this._previewBtn.classList.add("an-link-tooltip-btn--copied");
|
|
5909
|
-
this._previewBtn.title =
|
|
8619
|
+
this._previewBtn.title = this.context.locale.tooltips.video.exitPreview;
|
|
5910
8620
|
this._previewClickOff = (e) => {
|
|
5911
8621
|
if (!wrapper.contains(e.target) && !this._el.contains(e.target)) this._exitPreview();
|
|
5912
8622
|
};
|
|
@@ -5920,7 +8630,7 @@ var VideoTooltip = class {
|
|
|
5920
8630
|
if (shield) shield.style.display = "";
|
|
5921
8631
|
}
|
|
5922
8632
|
this._previewBtn.classList.remove("an-link-tooltip-btn--copied");
|
|
5923
|
-
this._previewBtn.title =
|
|
8633
|
+
this._previewBtn.title = this.context.locale.tooltips.video.previewVideo;
|
|
5924
8634
|
if (this._previewClickOff) {
|
|
5925
8635
|
document.removeEventListener("mousedown", this._previewClickOff, true);
|
|
5926
8636
|
this._previewClickOff = null;
|
|
@@ -6234,35 +8944,36 @@ var TableTooltip = class {
|
|
|
6234
8944
|
this._sizePopover = null;
|
|
6235
8945
|
}
|
|
6236
8946
|
_buildTooltip() {
|
|
8947
|
+
const L = this.context.locale.tooltips.table;
|
|
6237
8948
|
const el = createElement("div", {
|
|
6238
8949
|
class: "an-link-tooltip an-table-tooltip",
|
|
6239
8950
|
role: "toolbar",
|
|
6240
|
-
"aria-label":
|
|
8951
|
+
"aria-label": L.ariaLabel
|
|
6241
8952
|
});
|
|
6242
8953
|
el.style.display = "none";
|
|
6243
8954
|
this._label = createElement("span", { class: "an-link-tooltip-url" });
|
|
6244
|
-
this._label.textContent =
|
|
8955
|
+
this._label.textContent = L.label;
|
|
6245
8956
|
el.appendChild(this._label);
|
|
6246
8957
|
el.appendChild(this._sep());
|
|
6247
|
-
this._selectBtn = this._makeBtn(ICONS$2.selectCells,
|
|
8958
|
+
this._selectBtn = this._makeBtn(ICONS$2.selectCells, L.selectCells, () => this._toggleSelectMode());
|
|
6248
8959
|
el.appendChild(this._selectBtn);
|
|
6249
8960
|
el.appendChild(this._sep());
|
|
6250
|
-
el.appendChild(this._makeBtn(ICONS$2.rowAbove,
|
|
6251
|
-
el.appendChild(this._makeBtn(ICONS$2.rowBelow,
|
|
6252
|
-
el.appendChild(this._makeBtn(ICONS$2.deleteRow,
|
|
8961
|
+
el.appendChild(this._makeBtn(ICONS$2.rowAbove, L.addRowAbove, () => this._addRow("above")));
|
|
8962
|
+
el.appendChild(this._makeBtn(ICONS$2.rowBelow, L.addRowBelow, () => this._addRow("below")));
|
|
8963
|
+
el.appendChild(this._makeBtn(ICONS$2.deleteRow, L.deleteRow, () => this._deleteRow()));
|
|
6253
8964
|
el.appendChild(this._sep());
|
|
6254
|
-
el.appendChild(this._makeBtn(ICONS$2.colLeft,
|
|
6255
|
-
el.appendChild(this._makeBtn(ICONS$2.colRight,
|
|
6256
|
-
el.appendChild(this._makeBtn(ICONS$2.deleteCol,
|
|
8965
|
+
el.appendChild(this._makeBtn(ICONS$2.colLeft, L.addColumnLeft, () => this._addColumn("left")));
|
|
8966
|
+
el.appendChild(this._makeBtn(ICONS$2.colRight, L.addColumnRight, () => this._addColumn("right")));
|
|
8967
|
+
el.appendChild(this._makeBtn(ICONS$2.deleteCol, L.deleteColumn, () => this._deleteColumn()));
|
|
6257
8968
|
el.appendChild(this._sep());
|
|
6258
|
-
el.appendChild(this._makeBtn(ICONS$2.mergeCells,
|
|
6259
|
-
el.appendChild(this._makeBtn(ICONS$2.unmergeCells,
|
|
8969
|
+
el.appendChild(this._makeBtn(ICONS$2.mergeCells, L.mergeCells, () => this._mergeCells()));
|
|
8970
|
+
el.appendChild(this._makeBtn(ICONS$2.unmergeCells, L.unmergeCells, () => this._unmergeCells()));
|
|
6260
8971
|
el.appendChild(this._sep());
|
|
6261
|
-
el.appendChild(this._makeBtn(ICONS$2.colWidth,
|
|
6262
|
-
el.appendChild(this._makeBtn(ICONS$2.rowHeight,
|
|
6263
|
-
el.appendChild(this._makeBtn(ICONS$2.tableBorder,
|
|
8972
|
+
el.appendChild(this._makeBtn(ICONS$2.colWidth, L.columnWidth, () => this._openSizePopover("col")));
|
|
8973
|
+
el.appendChild(this._makeBtn(ICONS$2.rowHeight, L.rowHeight, () => this._openSizePopover("row")));
|
|
8974
|
+
el.appendChild(this._makeBtn(ICONS$2.tableBorder, L.tableBorderWidth, () => this._openSizePopover("border")));
|
|
6264
8975
|
el.appendChild(this._sep());
|
|
6265
|
-
el.appendChild(this._makeBtn(ICONS$2.deleteTable,
|
|
8976
|
+
el.appendChild(this._makeBtn(ICONS$2.deleteTable, L.deleteTable, () => this._deleteTable(), true));
|
|
6266
8977
|
this._disposers.push(on(el, "mouseenter", () => this._clearTimers()), on(el, "mouseleave", () => {
|
|
6267
8978
|
if (this._selectMode) return;
|
|
6268
8979
|
if (this._sizePopover && this._sizePopover.style.display !== "none") return;
|
|
@@ -6660,12 +9371,12 @@ var TableTooltip = class {
|
|
|
6660
9371
|
type: "button",
|
|
6661
9372
|
class: "an-btn"
|
|
6662
9373
|
});
|
|
6663
|
-
cancelBtn.textContent =
|
|
9374
|
+
cancelBtn.textContent = this.context.locale.tooltips.table.cancelBtn;
|
|
6664
9375
|
const applyBtn = createElement("button", {
|
|
6665
9376
|
type: "button",
|
|
6666
9377
|
class: "an-btn an-btn-primary"
|
|
6667
9378
|
});
|
|
6668
|
-
applyBtn.textContent =
|
|
9379
|
+
applyBtn.textContent = this.context.locale.tooltips.table.applyBtn;
|
|
6669
9380
|
actionsEl.appendChild(cancelBtn);
|
|
6670
9381
|
actionsEl.appendChild(applyBtn);
|
|
6671
9382
|
popover.appendChild(titleEl);
|
|
@@ -6703,7 +9414,7 @@ var TableTooltip = class {
|
|
|
6703
9414
|
if (!table) return;
|
|
6704
9415
|
const firstCell = table.querySelector("td, th");
|
|
6705
9416
|
const currentPx = firstCell ? parseInt(firstCell.style.borderWidth, 10) || parseInt(window.getComputedStyle(firstCell).borderWidth, 10) || 1 : 1;
|
|
6706
|
-
this._sizeTitleEl.textContent =
|
|
9417
|
+
this._sizeTitleEl.textContent = this.context.locale.tooltips.table.tableBorderWidthPx;
|
|
6707
9418
|
this._sizeInputEl.min = "0";
|
|
6708
9419
|
this._sizeInputEl.max = "10";
|
|
6709
9420
|
this._sizeInputEl.value = currentPx;
|
|
@@ -6725,7 +9436,7 @@ var TableTooltip = class {
|
|
|
6725
9436
|
const t = c.closest("table");
|
|
6726
9437
|
return t && t === cell.closest("table");
|
|
6727
9438
|
});
|
|
6728
|
-
this._sizeTitleEl.textContent = isCol ?
|
|
9439
|
+
this._sizeTitleEl.textContent = isCol ? this.context.locale.tooltips.table.columnWidthPx : this.context.locale.tooltips.table.rowHeightPx;
|
|
6729
9440
|
this._sizeInputEl.min = "1";
|
|
6730
9441
|
this._sizeInputEl.max = "2000";
|
|
6731
9442
|
this._sizeInputEl.value = isCol ? cell.offsetWidth || 120 : cell.closest("tr") ? cell.closest("tr").offsetHeight || 40 : 40;
|
|
@@ -6825,20 +9536,21 @@ var CodeTooltip = class {
|
|
|
6825
9536
|
this._el = null;
|
|
6826
9537
|
}
|
|
6827
9538
|
_buildTooltip() {
|
|
9539
|
+
const L = this.context.locale.tooltips.code;
|
|
6828
9540
|
const el = createElement("div", {
|
|
6829
9541
|
class: "an-link-tooltip an-code-tooltip",
|
|
6830
9542
|
role: "toolbar",
|
|
6831
|
-
"aria-label":
|
|
9543
|
+
"aria-label": L.ariaLabel
|
|
6832
9544
|
});
|
|
6833
9545
|
el.style.display = "none";
|
|
6834
9546
|
this._label = createElement("span", { class: "an-link-tooltip-url" });
|
|
6835
|
-
this._label.textContent =
|
|
9547
|
+
this._label.textContent = L.label;
|
|
6836
9548
|
el.appendChild(this._label);
|
|
6837
9549
|
el.appendChild(this._sep());
|
|
6838
9550
|
this._langSelect = createElement("select", {
|
|
6839
9551
|
class: "an-code-lang-select",
|
|
6840
|
-
title:
|
|
6841
|
-
"aria-label":
|
|
9552
|
+
title: L.syntaxLanguage,
|
|
9553
|
+
"aria-label": L.syntaxAriaLabel
|
|
6842
9554
|
});
|
|
6843
9555
|
[
|
|
6844
9556
|
["", "Plain text"],
|
|
@@ -6869,15 +9581,15 @@ var CodeTooltip = class {
|
|
|
6869
9581
|
this._disposers.push(on(this._langSelect, "change", () => this._onLangChange()));
|
|
6870
9582
|
el.appendChild(this._langSelect);
|
|
6871
9583
|
el.appendChild(this._sep());
|
|
6872
|
-
this._copyBtn = this._makeBtn(ICONS$1.copy,
|
|
9584
|
+
this._copyBtn = this._makeBtn(ICONS$1.copy, L.copyCode, () => this._copyCode());
|
|
6873
9585
|
el.appendChild(this._copyBtn);
|
|
6874
9586
|
el.appendChild(this._sep());
|
|
6875
|
-
this._wrapBtn = this._makeBtn(ICONS$1.wrapOn,
|
|
9587
|
+
this._wrapBtn = this._makeBtn(ICONS$1.wrapOn, L.toggleWordWrap, () => this._toggleWrap());
|
|
6876
9588
|
el.appendChild(this._wrapBtn);
|
|
6877
9589
|
el.appendChild(this._sep());
|
|
6878
|
-
el.appendChild(this._makeBtn(ICONS$1.toParagraph,
|
|
9590
|
+
el.appendChild(this._makeBtn(ICONS$1.toParagraph, L.convertToParagraph, () => this._toParagraph()));
|
|
6879
9591
|
el.appendChild(this._sep());
|
|
6880
|
-
el.appendChild(this._makeBtn(ICONS$1.deleteCode,
|
|
9592
|
+
el.appendChild(this._makeBtn(ICONS$1.deleteCode, L.deleteCodeBlock, () => this._delete(), true));
|
|
6881
9593
|
this._disposers.push(on(el, "mouseenter", () => this._clearTimers()), on(el, "mouseleave", () => this._scheduleHide()));
|
|
6882
9594
|
return el;
|
|
6883
9595
|
}
|
|
@@ -6954,7 +9666,7 @@ var CodeTooltip = class {
|
|
|
6954
9666
|
if (!this._activePre || !this._wrapBtn) return;
|
|
6955
9667
|
const wrapped = (this._activePre.style.whiteSpace || "").includes("pre-wrap") || window.getComputedStyle(this._activePre).whiteSpace === "pre-wrap";
|
|
6956
9668
|
this._wrapBtn.classList.toggle("active", wrapped);
|
|
6957
|
-
this._wrapBtn.title = wrapped ?
|
|
9669
|
+
this._wrapBtn.title = wrapped ? this.context.locale.tooltips.code.disableWordWrap : this.context.locale.tooltips.code.enableWordWrap;
|
|
6958
9670
|
}
|
|
6959
9671
|
_syncLangSelect() {
|
|
6960
9672
|
if (!this._activePre || !this._langSelect) return;
|
|
@@ -9484,27 +12196,28 @@ var EmojiDialog = class {
|
|
|
9484
12196
|
this._open();
|
|
9485
12197
|
}
|
|
9486
12198
|
_buildDialog() {
|
|
12199
|
+
const L = this.context.locale.emojiDialog;
|
|
9487
12200
|
const overlay = createElement("div", {
|
|
9488
12201
|
class: "an-dialog-overlay",
|
|
9489
12202
|
role: "dialog",
|
|
9490
12203
|
"aria-modal": "true",
|
|
9491
|
-
"aria-label":
|
|
12204
|
+
"aria-label": L.ariaLabel
|
|
9492
12205
|
});
|
|
9493
12206
|
const box = createElement("div", { class: "an-dialog-box an-emoji-box" });
|
|
9494
12207
|
const titleRow = createElement("div", { class: "an-icon-title-row" });
|
|
9495
12208
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
9496
|
-
title.textContent =
|
|
12209
|
+
title.textContent = L.title;
|
|
9497
12210
|
const closeBtn = createElement("button", {
|
|
9498
12211
|
type: "button",
|
|
9499
12212
|
class: "an-icon-close",
|
|
9500
|
-
"aria-label":
|
|
12213
|
+
"aria-label": L.close
|
|
9501
12214
|
});
|
|
9502
12215
|
closeBtn.innerHTML = "×";
|
|
9503
12216
|
titleRow.append(title, closeBtn);
|
|
9504
12217
|
const searchInput = createElement("input", {
|
|
9505
12218
|
type: "search",
|
|
9506
12219
|
class: "an-input an-icon-search",
|
|
9507
|
-
placeholder:
|
|
12220
|
+
placeholder: L.searchPlaceholder,
|
|
9508
12221
|
autocomplete: "off"
|
|
9509
12222
|
});
|
|
9510
12223
|
this._searchInput = searchInput;
|
|
@@ -9514,7 +12227,7 @@ var EmojiDialog = class {
|
|
|
9514
12227
|
class: "an-icon-cat active",
|
|
9515
12228
|
"data-cat": "all"
|
|
9516
12229
|
});
|
|
9517
|
-
allTab.textContent =
|
|
12230
|
+
allTab.textContent = L.all;
|
|
9518
12231
|
catBar.appendChild(allTab);
|
|
9519
12232
|
EMOJI_CATS.forEach(({ id, label }) => {
|
|
9520
12233
|
const tab = createElement("button", {
|
|
@@ -9522,7 +12235,7 @@ var EmojiDialog = class {
|
|
|
9522
12235
|
class: "an-icon-cat",
|
|
9523
12236
|
"data-cat": id
|
|
9524
12237
|
});
|
|
9525
|
-
tab.textContent = label;
|
|
12238
|
+
tab.textContent = L.categories && L.categories[id] || label;
|
|
9526
12239
|
catBar.appendChild(tab);
|
|
9527
12240
|
});
|
|
9528
12241
|
this._catBar = catBar;
|
|
@@ -9545,7 +12258,7 @@ var EmojiDialog = class {
|
|
|
9545
12258
|
type: "button",
|
|
9546
12259
|
class: "an-btn"
|
|
9547
12260
|
});
|
|
9548
|
-
cancelBtn.textContent =
|
|
12261
|
+
cancelBtn.textContent = L.cancelBtn;
|
|
9549
12262
|
btnRow.appendChild(cancelBtn);
|
|
9550
12263
|
box.append(titleRow, searchInput, catBar, grid, btnRow);
|
|
9551
12264
|
overlay.appendChild(box);
|
|
@@ -9956,27 +12669,28 @@ var IconDialog = class {
|
|
|
9956
12669
|
this._open();
|
|
9957
12670
|
}
|
|
9958
12671
|
_buildDialog() {
|
|
12672
|
+
const L = this.context.locale.iconDialog;
|
|
9959
12673
|
const overlay = createElement("div", {
|
|
9960
12674
|
class: "an-dialog-overlay",
|
|
9961
12675
|
role: "dialog",
|
|
9962
12676
|
"aria-modal": "true",
|
|
9963
|
-
"aria-label":
|
|
12677
|
+
"aria-label": L.ariaLabel
|
|
9964
12678
|
});
|
|
9965
12679
|
const box = createElement("div", { class: "an-dialog-box an-icon-box" });
|
|
9966
12680
|
const titleRow = createElement("div", { class: "an-icon-title-row" });
|
|
9967
12681
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
9968
|
-
title.textContent =
|
|
12682
|
+
title.textContent = L.title;
|
|
9969
12683
|
const closeBtn = createElement("button", {
|
|
9970
12684
|
type: "button",
|
|
9971
12685
|
class: "an-icon-close",
|
|
9972
|
-
"aria-label":
|
|
12686
|
+
"aria-label": L.close
|
|
9973
12687
|
});
|
|
9974
12688
|
closeBtn.innerHTML = "×";
|
|
9975
12689
|
titleRow.append(title, closeBtn);
|
|
9976
12690
|
const searchInput = createElement("input", {
|
|
9977
12691
|
type: "search",
|
|
9978
12692
|
class: "an-input an-icon-search",
|
|
9979
|
-
placeholder:
|
|
12693
|
+
placeholder: L.searchPlaceholder,
|
|
9980
12694
|
autocomplete: "off"
|
|
9981
12695
|
});
|
|
9982
12696
|
this._searchInput = searchInput;
|
|
@@ -9986,7 +12700,7 @@ var IconDialog = class {
|
|
|
9986
12700
|
class: "an-icon-cat active",
|
|
9987
12701
|
"data-cat": "all"
|
|
9988
12702
|
});
|
|
9989
|
-
allTab.textContent =
|
|
12703
|
+
allTab.textContent = L.all;
|
|
9990
12704
|
catBar.appendChild(allTab);
|
|
9991
12705
|
ICON_CATEGORIES.forEach(({ id, label }) => {
|
|
9992
12706
|
const tab = createElement("button", {
|
|
@@ -9994,7 +12708,7 @@ var IconDialog = class {
|
|
|
9994
12708
|
class: "an-icon-cat",
|
|
9995
12709
|
"data-cat": id
|
|
9996
12710
|
});
|
|
9997
|
-
tab.textContent = label;
|
|
12711
|
+
tab.textContent = L.categories && L.categories[id] || label;
|
|
9998
12712
|
catBar.appendChild(tab);
|
|
9999
12713
|
});
|
|
10000
12714
|
this._catBar = catBar;
|
|
@@ -10019,7 +12733,7 @@ var IconDialog = class {
|
|
|
10019
12733
|
this._grid = grid;
|
|
10020
12734
|
const optRow = createElement("div", { class: "an-icon-options" });
|
|
10021
12735
|
const styleLabel = createElement("label", { class: "an-label" });
|
|
10022
|
-
styleLabel.textContent =
|
|
12736
|
+
styleLabel.textContent = L.style;
|
|
10023
12737
|
const styleSelect = createElement("select", { class: "an-input an-icon-option-select" });
|
|
10024
12738
|
[
|
|
10025
12739
|
["fa-solid", "Solid"],
|
|
@@ -10033,7 +12747,7 @@ var IconDialog = class {
|
|
|
10033
12747
|
styleSelect.value = "fa-solid";
|
|
10034
12748
|
this._styleSelect = styleSelect;
|
|
10035
12749
|
const sizeLabel = createElement("label", { class: "an-label" });
|
|
10036
|
-
sizeLabel.textContent =
|
|
12750
|
+
sizeLabel.textContent = L.size;
|
|
10037
12751
|
const sizeSelect = createElement("select", { class: "an-input an-icon-option-select" });
|
|
10038
12752
|
[
|
|
10039
12753
|
["", "Inherit"],
|
|
@@ -10051,7 +12765,7 @@ var IconDialog = class {
|
|
|
10051
12765
|
});
|
|
10052
12766
|
this._sizeSelect = sizeSelect;
|
|
10053
12767
|
const colorLabel = createElement("label", { class: "an-label" });
|
|
10054
|
-
colorLabel.textContent =
|
|
12768
|
+
colorLabel.textContent = L.color;
|
|
10055
12769
|
const colorInput = createElement("input", {
|
|
10056
12770
|
type: "color",
|
|
10057
12771
|
class: "an-icon-color",
|
|
@@ -10064,11 +12778,11 @@ var IconDialog = class {
|
|
|
10064
12778
|
checked: ""
|
|
10065
12779
|
});
|
|
10066
12780
|
this._useColorCb = useColorCb;
|
|
10067
|
-
useColorLabel.append(useColorCb, document.createTextNode(
|
|
12781
|
+
useColorLabel.append(useColorCb, document.createTextNode(L.useColor));
|
|
10068
12782
|
optRow.append(styleLabel, styleSelect, sizeLabel, sizeSelect, colorLabel, colorInput, useColorLabel);
|
|
10069
12783
|
const preview = createElement("div", { class: "an-icon-preview" });
|
|
10070
12784
|
const previewHint = createElement("span", { class: "an-icon-preview-hint" });
|
|
10071
|
-
previewHint.textContent =
|
|
12785
|
+
previewHint.textContent = L.selectHint;
|
|
10072
12786
|
preview.appendChild(previewHint);
|
|
10073
12787
|
this._preview = preview;
|
|
10074
12788
|
const btnRow = createElement("div", { class: "an-dialog-actions" });
|
|
@@ -10077,12 +12791,12 @@ var IconDialog = class {
|
|
|
10077
12791
|
class: "an-btn an-btn-primary",
|
|
10078
12792
|
disabled: ""
|
|
10079
12793
|
});
|
|
10080
|
-
insertBtn.textContent =
|
|
12794
|
+
insertBtn.textContent = L.insertBtn;
|
|
10081
12795
|
const cancelBtn = createElement("button", {
|
|
10082
12796
|
type: "button",
|
|
10083
12797
|
class: "an-btn"
|
|
10084
12798
|
});
|
|
10085
|
-
cancelBtn.textContent =
|
|
12799
|
+
cancelBtn.textContent = L.cancelBtn;
|
|
10086
12800
|
btnRow.append(insertBtn, cancelBtn);
|
|
10087
12801
|
this._insertBtn = insertBtn;
|
|
10088
12802
|
box.append(titleRow, searchInput, catBar, grid, optRow, preview, btnRow);
|
|
@@ -10283,9 +12997,11 @@ var COLOR_PRESETS = [
|
|
|
10283
12997
|
];
|
|
10284
12998
|
function makeColorSubItems(colorType) {
|
|
10285
12999
|
const label = colorType === "foreColor" ? "Text Color" : "Highlight Color";
|
|
13000
|
+
const localeKey = colorType === "foreColor" ? "textColor" : "highlightColor";
|
|
10286
13001
|
return () => [{
|
|
10287
13002
|
back: true,
|
|
10288
13003
|
label,
|
|
13004
|
+
localeKey,
|
|
10289
13005
|
navigate: () => defaultItems
|
|
10290
13006
|
}, {
|
|
10291
13007
|
colorPalette: true,
|
|
@@ -10482,7 +13198,8 @@ var ContextMenu = class {
|
|
|
10482
13198
|
});
|
|
10483
13199
|
iconSpan.innerHTML = ICONS.back;
|
|
10484
13200
|
backBtn.appendChild(iconSpan);
|
|
10485
|
-
|
|
13201
|
+
const backLabel = it.localeKey && this.context.locale.contextMenu[it.localeKey] || it.label || this.context.locale.contextMenu.back || "Back";
|
|
13202
|
+
backBtn.appendChild(createElement("span", { class: "an-context-label" }, [backLabel]));
|
|
10486
13203
|
const off = on(backBtn, "click", (e) => {
|
|
10487
13204
|
e.stopPropagation();
|
|
10488
13205
|
const curLeft = parseFloat(this.el.style.left);
|
|
@@ -10520,7 +13237,7 @@ var ContextMenu = class {
|
|
|
10520
13237
|
iconSpan.innerHTML = it.icon;
|
|
10521
13238
|
btn.appendChild(iconSpan);
|
|
10522
13239
|
}
|
|
10523
|
-
btn.appendChild(createElement("span", { class: "an-context-label" }, [it.label || it.name]));
|
|
13240
|
+
btn.appendChild(createElement("span", { class: "an-context-label" }, [this.context.locale.contextMenu[it.name] || it.label || it.name]));
|
|
10524
13241
|
const chevron = createElement("span", {
|
|
10525
13242
|
class: "an-context-chevron",
|
|
10526
13243
|
"aria-hidden": "true"
|
|
@@ -10558,9 +13275,9 @@ var ContextMenu = class {
|
|
|
10558
13275
|
if (it.colorType === "hiliteColor") {
|
|
10559
13276
|
const noColor = createElement("div", {
|
|
10560
13277
|
class: "an-context-color-swatch an-context-color-none",
|
|
10561
|
-
title: "No highlight",
|
|
13278
|
+
title: this.context.locale.contextMenu.noHighlight || "No highlight",
|
|
10562
13279
|
role: "button",
|
|
10563
|
-
"aria-label": "No highlight"
|
|
13280
|
+
"aria-label": this.context.locale.contextMenu.noHighlight || "No highlight"
|
|
10564
13281
|
});
|
|
10565
13282
|
noColor.innerHTML = ICONS.noColor;
|
|
10566
13283
|
const offNo = on(noColor, "click", (e) => {
|
|
@@ -10575,10 +13292,10 @@ var ContextMenu = class {
|
|
|
10575
13292
|
const colorInput = createElement("input", {
|
|
10576
13293
|
type: "color",
|
|
10577
13294
|
value: it.colorType === "foreColor" ? "#000000" : "#ffff00",
|
|
10578
|
-
title: "Custom color",
|
|
10579
|
-
"aria-label": "Custom color"
|
|
13295
|
+
title: this.context.locale.contextMenu.customColor || "Custom color",
|
|
13296
|
+
"aria-label": this.context.locale.contextMenu.customColor || "Custom color"
|
|
10580
13297
|
});
|
|
10581
|
-
const customLabel = createElement("span", {}, ["Custom…"]);
|
|
13298
|
+
const customLabel = createElement("span", {}, [this.context.locale.contextMenu.customColorLabel || "Custom…"]);
|
|
10582
13299
|
const offCustom = on(colorInput, "change", () => this._applyColor(it.colorType, colorInput.value));
|
|
10583
13300
|
this._menuDisposers.push(offCustom);
|
|
10584
13301
|
customRow.appendChild(colorInput);
|
|
@@ -10602,7 +13319,7 @@ var ContextMenu = class {
|
|
|
10602
13319
|
iconSpan.innerHTML = it.icon;
|
|
10603
13320
|
headerBtn.appendChild(iconSpan);
|
|
10604
13321
|
}
|
|
10605
|
-
headerBtn.appendChild(createElement("span", { class: "an-context-label" }, [it.label || "Insert Table"]));
|
|
13322
|
+
headerBtn.appendChild(createElement("span", { class: "an-context-label" }, [this.context.locale.contextMenu.table || it.label || "Insert Table"]));
|
|
10606
13323
|
const chevron = createElement("span", {
|
|
10607
13324
|
class: "an-context-chevron",
|
|
10608
13325
|
"aria-hidden": "true"
|
|
@@ -10631,7 +13348,7 @@ var ContextMenu = class {
|
|
|
10631
13348
|
cells.forEach((cell) => {
|
|
10632
13349
|
cell.classList.toggle("active", +cell.dataset.row <= rows && +cell.dataset.col <= cols);
|
|
10633
13350
|
});
|
|
10634
|
-
labelEl.textContent = rows && cols ? `${cols} × ${rows}` : "Insert Table";
|
|
13351
|
+
labelEl.textContent = rows && cols ? `${cols} × ${rows}` : this.context.locale.contextMenu.table || "Insert Table";
|
|
10635
13352
|
};
|
|
10636
13353
|
panel.appendChild(gridEl);
|
|
10637
13354
|
panel.appendChild(labelEl);
|
|
@@ -10685,7 +13402,7 @@ var ContextMenu = class {
|
|
|
10685
13402
|
iconSpan.innerHTML = it.icon;
|
|
10686
13403
|
btn.appendChild(iconSpan);
|
|
10687
13404
|
}
|
|
10688
|
-
btn.appendChild(createElement("span", { class: "an-context-label" }, [it.label || it.name]));
|
|
13405
|
+
btn.appendChild(createElement("span", { class: "an-context-label" }, [this.context.locale.contextMenu[it.name] || it.label || it.name]));
|
|
10689
13406
|
const off = on(btn, "click", (e) => {
|
|
10690
13407
|
e.stopPropagation();
|
|
10691
13408
|
this.hide();
|
|
@@ -10705,12 +13422,18 @@ var ContextMenu = class {
|
|
|
10705
13422
|
if (!editable.contains(event.target)) return;
|
|
10706
13423
|
if (this.context.layoutInfo.container.classList.contains("an-disabled")) return;
|
|
10707
13424
|
event.preventDefault();
|
|
10708
|
-
this._lastX = event.clientX;
|
|
10709
|
-
this._lastY = event.clientY;
|
|
10710
13425
|
const winSel = window.getSelection();
|
|
10711
13426
|
this._savedRange = winSel && winSel.rangeCount > 0 ? winSel.getRangeAt(0).cloneRange() : null;
|
|
10712
13427
|
this._renderItems(this._items);
|
|
10713
|
-
|
|
13428
|
+
let openX = event.clientX;
|
|
13429
|
+
let openY = event.clientY;
|
|
13430
|
+
if (this._savedRange && !this._savedRange.collapsed) try {
|
|
13431
|
+
const selRect = this._savedRange.getBoundingClientRect();
|
|
13432
|
+
if (selRect.width > 0 && selRect.height > 0) openY = selRect.bottom + 4;
|
|
13433
|
+
} catch (_) {}
|
|
13434
|
+
this._lastX = openX;
|
|
13435
|
+
this._lastY = openY;
|
|
13436
|
+
this.showAt(openX, openY);
|
|
10714
13437
|
}
|
|
10715
13438
|
_maybeHide(event) {
|
|
10716
13439
|
if (!this.el) return;
|
|
@@ -10721,28 +13444,20 @@ var ContextMenu = class {
|
|
|
10721
13444
|
this.el.style.display = "block";
|
|
10722
13445
|
this._reposition(x, y);
|
|
10723
13446
|
this.el.setAttribute("aria-hidden", "false");
|
|
13447
|
+
this.context.triggerEvent("contextMenu:show");
|
|
10724
13448
|
}
|
|
10725
13449
|
_reposition(x, y) {
|
|
10726
13450
|
if (!this.el) return;
|
|
10727
13451
|
const rx = x !== void 0 ? x : this._lastX;
|
|
10728
13452
|
const ry = y !== void 0 ? y : this._lastY;
|
|
10729
|
-
const
|
|
13453
|
+
const w = this.el.offsetWidth;
|
|
13454
|
+
const h = this.el.offsetHeight;
|
|
10730
13455
|
let left = rx;
|
|
10731
13456
|
let top = ry;
|
|
10732
|
-
if (left +
|
|
13457
|
+
if (left + w > window.innerWidth - 8) left = window.innerWidth - w - 8;
|
|
10733
13458
|
if (left < 8) left = 8;
|
|
10734
|
-
if (top +
|
|
13459
|
+
if (top + h > window.innerHeight - 8) top = window.innerHeight - h - 8;
|
|
10735
13460
|
if (top < 8) top = 8;
|
|
10736
|
-
if (this._savedRange) try {
|
|
10737
|
-
const sel = this._savedRange.getBoundingClientRect();
|
|
10738
|
-
if (sel.width > 0 || sel.height > 0) {
|
|
10739
|
-
if (top < sel.bottom && top + rect.height > sel.top && left < sel.right && left + rect.width > sel.left) {
|
|
10740
|
-
const belowTop = sel.bottom + 6;
|
|
10741
|
-
if (belowTop + rect.height <= window.innerHeight - 8) top = belowTop;
|
|
10742
|
-
else top = Math.max(8, sel.top - rect.height - 6);
|
|
10743
|
-
}
|
|
10744
|
-
}
|
|
10745
|
-
} catch (_) {}
|
|
10746
13461
|
this.el.style.left = `${left}px`;
|
|
10747
13462
|
this.el.style.top = `${top}px`;
|
|
10748
13463
|
}
|
|
@@ -10750,6 +13465,7 @@ var ContextMenu = class {
|
|
|
10750
13465
|
if (!this.el) return;
|
|
10751
13466
|
this.el.style.display = "none";
|
|
10752
13467
|
this.el.setAttribute("aria-hidden", "true");
|
|
13468
|
+
this.context.triggerEvent("contextMenu:hide");
|
|
10753
13469
|
}
|
|
10754
13470
|
/** Read the current selection's text or highlight color for the strip.
|
|
10755
13471
|
* @param {'foreColor'|'hiliteColor'} type
|
|
@@ -10999,22 +13715,22 @@ var ShortcutsDialog = class {
|
|
|
10999
13715
|
class: "an-dialog-overlay",
|
|
11000
13716
|
role: "dialog",
|
|
11001
13717
|
"aria-modal": "true",
|
|
11002
|
-
"aria-label":
|
|
13718
|
+
"aria-label": this.context.locale.shortcutsDialog.ariaLabel
|
|
11003
13719
|
});
|
|
11004
13720
|
const box = createElement("div", { class: "an-dialog-box an-shortcuts-box" });
|
|
11005
13721
|
const titleRow = createElement("div", { class: "an-icon-title-row" });
|
|
11006
13722
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
11007
|
-
title.textContent =
|
|
13723
|
+
title.textContent = this.context.locale.shortcutsDialog.title;
|
|
11008
13724
|
const closeBtn = createElement("button", {
|
|
11009
13725
|
type: "button",
|
|
11010
13726
|
class: "an-icon-close",
|
|
11011
|
-
"aria-label":
|
|
13727
|
+
"aria-label": this.context.locale.shortcutsDialog.close
|
|
11012
13728
|
});
|
|
11013
13729
|
closeBtn.textContent = "×";
|
|
11014
13730
|
this._closeBtn = closeBtn;
|
|
11015
13731
|
titleRow.append(title, closeBtn);
|
|
11016
13732
|
box.appendChild(titleRow);
|
|
11017
|
-
SHORTCUTS.forEach(({ category, items }) => {
|
|
13733
|
+
(this.context.locale.shortcutsDialog.shortcuts || SHORTCUTS).forEach(({ category, items }) => {
|
|
11018
13734
|
const catEl = createElement("div", { class: "an-shortcuts-cat" });
|
|
11019
13735
|
catEl.textContent = category;
|
|
11020
13736
|
box.appendChild(catEl);
|
|
@@ -11139,25 +13855,26 @@ var FindReplace = class {
|
|
|
11139
13855
|
const isReplace = this._mode === "replace";
|
|
11140
13856
|
if (replaceRow) replaceRow.style.display = isReplace ? "" : "none";
|
|
11141
13857
|
if (replaceActions) replaceActions.style.display = isReplace ? "" : "none";
|
|
11142
|
-
if (title) title.textContent = isReplace ?
|
|
13858
|
+
if (title) title.textContent = isReplace ? this.context.locale.findReplace.findReplaceTitle : this.context.locale.findReplace.findTitle;
|
|
11143
13859
|
}
|
|
11144
13860
|
_buildDialog() {
|
|
13861
|
+
const L = this.context.locale.findReplace;
|
|
11145
13862
|
const overlay = createElement("div", {
|
|
11146
13863
|
class: "an-dialog-overlay an-fr-dialog",
|
|
11147
13864
|
role: "dialog",
|
|
11148
13865
|
"aria-modal": "true",
|
|
11149
|
-
"aria-label":
|
|
13866
|
+
"aria-label": L.findReplaceTitle
|
|
11150
13867
|
});
|
|
11151
13868
|
const box = createElement("div", { class: "an-dialog-box" });
|
|
11152
13869
|
const titleRow = createElement("div", { class: "an-icon-title-row" });
|
|
11153
13870
|
const title = createElement("h3", { class: "an-dialog-title" });
|
|
11154
|
-
title.textContent =
|
|
13871
|
+
title.textContent = L.findTitle;
|
|
11155
13872
|
const closeBtn = createElement("button", {
|
|
11156
13873
|
type: "button",
|
|
11157
13874
|
class: "an-icon-close",
|
|
11158
13875
|
"aria-label": "Close"
|
|
11159
13876
|
});
|
|
11160
|
-
closeBtn.textContent =
|
|
13877
|
+
closeBtn.textContent = L.close;
|
|
11161
13878
|
this._closeBtn = closeBtn;
|
|
11162
13879
|
titleRow.append(title, closeBtn);
|
|
11163
13880
|
box.appendChild(titleRow);
|
|
@@ -11165,8 +13882,8 @@ var FindReplace = class {
|
|
|
11165
13882
|
const findInput = createElement("input", {
|
|
11166
13883
|
type: "text",
|
|
11167
13884
|
class: "an-input",
|
|
11168
|
-
placeholder:
|
|
11169
|
-
"aria-label":
|
|
13885
|
+
placeholder: L.findPlaceholder,
|
|
13886
|
+
"aria-label": L.searchAriaLabel
|
|
11170
13887
|
});
|
|
11171
13888
|
this._findInput = findInput;
|
|
11172
13889
|
findRow.appendChild(findInput);
|
|
@@ -11178,7 +13895,7 @@ var FindReplace = class {
|
|
|
11178
13895
|
"aria-label": "Case sensitive"
|
|
11179
13896
|
});
|
|
11180
13897
|
this._caseCheckbox = caseCheckbox;
|
|
11181
|
-
caseLabel.append(caseCheckbox, document.createTextNode(
|
|
13898
|
+
caseLabel.append(caseCheckbox, document.createTextNode(L.caseSensitive));
|
|
11182
13899
|
const counter = createElement("span", { class: "an-fr-counter" });
|
|
11183
13900
|
this._counterEl = counter;
|
|
11184
13901
|
optRow.append(caseLabel, counter);
|
|
@@ -11188,12 +13905,12 @@ var FindReplace = class {
|
|
|
11188
13905
|
type: "button",
|
|
11189
13906
|
class: "an-btn"
|
|
11190
13907
|
});
|
|
11191
|
-
prevBtn.textContent =
|
|
13908
|
+
prevBtn.textContent = L.prevBtn;
|
|
11192
13909
|
const nextBtn = createElement("button", {
|
|
11193
13910
|
type: "button",
|
|
11194
13911
|
class: "an-btn an-btn-primary"
|
|
11195
13912
|
});
|
|
11196
|
-
nextBtn.textContent =
|
|
13913
|
+
nextBtn.textContent = L.nextBtn;
|
|
11197
13914
|
findActions.append(prevBtn, nextBtn);
|
|
11198
13915
|
box.appendChild(findActions);
|
|
11199
13916
|
const replaceRow = createElement("div", { class: "an-fr-replace-row" });
|
|
@@ -11201,8 +13918,8 @@ var FindReplace = class {
|
|
|
11201
13918
|
const replaceInput = createElement("input", {
|
|
11202
13919
|
type: "text",
|
|
11203
13920
|
class: "an-input",
|
|
11204
|
-
placeholder:
|
|
11205
|
-
"aria-label":
|
|
13921
|
+
placeholder: L.replacePlaceholder,
|
|
13922
|
+
"aria-label": L.replaceAriaLabel
|
|
11206
13923
|
});
|
|
11207
13924
|
this._replaceInput = replaceInput;
|
|
11208
13925
|
replaceRow.appendChild(replaceInput);
|
|
@@ -11213,12 +13930,12 @@ var FindReplace = class {
|
|
|
11213
13930
|
type: "button",
|
|
11214
13931
|
class: "an-btn"
|
|
11215
13932
|
});
|
|
11216
|
-
replaceBtn.textContent =
|
|
13933
|
+
replaceBtn.textContent = L.replaceBtn;
|
|
11217
13934
|
const replaceAllBtn = createElement("button", {
|
|
11218
13935
|
type: "button",
|
|
11219
13936
|
class: "an-btn an-btn-primary"
|
|
11220
13937
|
});
|
|
11221
|
-
replaceAllBtn.textContent =
|
|
13938
|
+
replaceAllBtn.textContent = L.replaceAllBtn;
|
|
11222
13939
|
replaceActions.append(replaceBtn, replaceAllBtn);
|
|
11223
13940
|
box.appendChild(replaceActions);
|
|
11224
13941
|
overlay.appendChild(box);
|
|
@@ -11863,6 +14580,771 @@ var ImageCropOverlay = class {
|
|
|
11863
14580
|
}
|
|
11864
14581
|
};
|
|
11865
14582
|
//#endregion
|
|
14583
|
+
//#region src/js/module/AutoSaveRestore.js
|
|
14584
|
+
/**
|
|
14585
|
+
* AutoSaveRestore.js — Detects a previously auto-saved draft and offers the
|
|
14586
|
+
* user a banner to restore or discard it.
|
|
14587
|
+
*
|
|
14588
|
+
* Activated when both `autoSave` and `autoSaveRestore` options are true.
|
|
14589
|
+
* On initialize it checks localStorage for a draft that is within the
|
|
14590
|
+
* `autoSaveRestoreTimeout` day window. If one is found a dismissible banner
|
|
14591
|
+
* is prepended to the editor container.
|
|
14592
|
+
*/
|
|
14593
|
+
var AutoSaveRestore = class {
|
|
14594
|
+
/** @param {import('../Context.js').Context} context */
|
|
14595
|
+
constructor(context) {
|
|
14596
|
+
this.context = context;
|
|
14597
|
+
this.options = context.options;
|
|
14598
|
+
/** @type {HTMLElement|null} */
|
|
14599
|
+
this._banner = null;
|
|
14600
|
+
}
|
|
14601
|
+
initialize() {
|
|
14602
|
+
if (!this.options.autoSave || !this.options.autoSaveRestore) return this;
|
|
14603
|
+
const key = this.options.autoSaveKey;
|
|
14604
|
+
const metaKey = key + ":asrmeta";
|
|
14605
|
+
let saved;
|
|
14606
|
+
let meta;
|
|
14607
|
+
try {
|
|
14608
|
+
saved = localStorage.getItem(key);
|
|
14609
|
+
meta = JSON.parse(localStorage.getItem(metaKey) || "{}");
|
|
14610
|
+
} catch (_) {
|
|
14611
|
+
return this;
|
|
14612
|
+
}
|
|
14613
|
+
if (!saved) return this;
|
|
14614
|
+
const timeout = this.options.autoSaveRestoreTimeout;
|
|
14615
|
+
if (timeout > 0) {
|
|
14616
|
+
if (Date.now() - (meta.savedAt || 0) > timeout * 864e5) {
|
|
14617
|
+
try {
|
|
14618
|
+
localStorage.removeItem(key);
|
|
14619
|
+
localStorage.removeItem(metaKey);
|
|
14620
|
+
} catch (_) {}
|
|
14621
|
+
return this;
|
|
14622
|
+
}
|
|
14623
|
+
}
|
|
14624
|
+
this._showBanner(saved, meta);
|
|
14625
|
+
return this;
|
|
14626
|
+
}
|
|
14627
|
+
destroy() {
|
|
14628
|
+
this._removeBanner();
|
|
14629
|
+
}
|
|
14630
|
+
_showBanner(draftHtml, meta) {
|
|
14631
|
+
const t = this.context.locale.autoSaveRestore || {};
|
|
14632
|
+
const label = t.found || "Draft found. Restore?";
|
|
14633
|
+
const restoreLabel = t.restore || "Restore";
|
|
14634
|
+
const discardLabel = t.discard || "Discard";
|
|
14635
|
+
const banner = document.createElement("div");
|
|
14636
|
+
banner.className = "an-asr-banner";
|
|
14637
|
+
banner.setAttribute("role", "alert");
|
|
14638
|
+
const msg = document.createElement("span");
|
|
14639
|
+
msg.className = "an-asr-msg";
|
|
14640
|
+
if (meta.savedAt) {
|
|
14641
|
+
const formatted = new Date(meta.savedAt).toLocaleString();
|
|
14642
|
+
msg.textContent = (t.foundAt || "Draft from {date}. Restore?").replace("{date}", formatted);
|
|
14643
|
+
} else msg.textContent = label;
|
|
14644
|
+
const restoreBtn = document.createElement("button");
|
|
14645
|
+
restoreBtn.type = "button";
|
|
14646
|
+
restoreBtn.className = "an-btn an-asr-btn-restore";
|
|
14647
|
+
restoreBtn.textContent = restoreLabel;
|
|
14648
|
+
restoreBtn.addEventListener("click", () => this._restore(draftHtml));
|
|
14649
|
+
const discardBtn = document.createElement("button");
|
|
14650
|
+
discardBtn.type = "button";
|
|
14651
|
+
discardBtn.className = "an-btn an-asr-btn-discard";
|
|
14652
|
+
discardBtn.textContent = discardLabel;
|
|
14653
|
+
discardBtn.addEventListener("click", () => this._discard());
|
|
14654
|
+
banner.appendChild(msg);
|
|
14655
|
+
banner.appendChild(restoreBtn);
|
|
14656
|
+
banner.appendChild(discardBtn);
|
|
14657
|
+
this._banner = banner;
|
|
14658
|
+
const container = this.context.layoutInfo.container;
|
|
14659
|
+
container.insertBefore(banner, container.firstChild);
|
|
14660
|
+
}
|
|
14661
|
+
_restore(draftHtml) {
|
|
14662
|
+
this.context.setHTML(draftHtml);
|
|
14663
|
+
this.context.clearHistory();
|
|
14664
|
+
this._removeBanner();
|
|
14665
|
+
if (typeof this.options.onAutoSaveRestore === "function") this.options.onAutoSaveRestore(draftHtml, this.context);
|
|
14666
|
+
}
|
|
14667
|
+
_discard() {
|
|
14668
|
+
const key = this.options.autoSaveKey;
|
|
14669
|
+
try {
|
|
14670
|
+
localStorage.removeItem(key);
|
|
14671
|
+
localStorage.removeItem(key + ":asrmeta");
|
|
14672
|
+
} catch (_) {}
|
|
14673
|
+
this._removeBanner();
|
|
14674
|
+
}
|
|
14675
|
+
_removeBanner() {
|
|
14676
|
+
if (this._banner && this._banner.parentNode) this._banner.parentNode.removeChild(this._banner);
|
|
14677
|
+
this._banner = null;
|
|
14678
|
+
}
|
|
14679
|
+
};
|
|
14680
|
+
//#endregion
|
|
14681
|
+
//#region src/js/module/MarkdownShortcuts.js
|
|
14682
|
+
/**
|
|
14683
|
+
* MarkdownShortcuts.js — Convert Markdown-style syntax typed directly in the
|
|
14684
|
+
* editor into rich HTML elements (input rules / auto-format).
|
|
14685
|
+
*
|
|
14686
|
+
* Activated when `markdownShortcuts: true` (the default).
|
|
14687
|
+
*
|
|
14688
|
+
* Block rules — triggered by Space or Enter at the start of a line:
|
|
14689
|
+
* #[#[#]]· → H1 / H2 / H3
|
|
14690
|
+
* >· → blockquote
|
|
14691
|
+
* -· or *· → unordered list item
|
|
14692
|
+
* 1.· → ordered list item
|
|
14693
|
+
* [ ]· → checklist item
|
|
14694
|
+
* --- → horizontal rule (on Enter)
|
|
14695
|
+
* ``` → code block (on Enter)
|
|
14696
|
+
*
|
|
14697
|
+
* Inline rules — triggered when the closing marker is typed:
|
|
14698
|
+
* **text** → <strong>
|
|
14699
|
+
* *text* → <em>
|
|
14700
|
+
* ~~text~~ → <s>
|
|
14701
|
+
* `code` → <code>
|
|
14702
|
+
*/
|
|
14703
|
+
var MarkdownShortcuts = class {
|
|
14704
|
+
/** @param {import('../Context.js').Context} context */
|
|
14705
|
+
constructor(context) {
|
|
14706
|
+
this.context = context;
|
|
14707
|
+
this.options = context.options;
|
|
14708
|
+
this._disposers = [];
|
|
14709
|
+
}
|
|
14710
|
+
initialize() {
|
|
14711
|
+
if (!this.options.markdownShortcuts) return this;
|
|
14712
|
+
const editable = this.context.layoutInfo.editable;
|
|
14713
|
+
const d1 = on(
|
|
14714
|
+
editable,
|
|
14715
|
+
"keydown",
|
|
14716
|
+
/** @param {KeyboardEvent} e */
|
|
14717
|
+
(e) => this._onKeydown(e)
|
|
14718
|
+
);
|
|
14719
|
+
const d2 = on(editable, "input", () => this._onInput());
|
|
14720
|
+
this._disposers.push(d1, d2);
|
|
14721
|
+
return this;
|
|
14722
|
+
}
|
|
14723
|
+
destroy() {
|
|
14724
|
+
this._disposers.forEach((d) => d());
|
|
14725
|
+
this._disposers = [];
|
|
14726
|
+
}
|
|
14727
|
+
_onKeydown(e) {
|
|
14728
|
+
if (e.key === " ") {
|
|
14729
|
+
if (this._applyBlockRule()) e.preventDefault();
|
|
14730
|
+
} else if (e.key === "Enter") {
|
|
14731
|
+
if (this._applyEnterRule()) e.preventDefault();
|
|
14732
|
+
}
|
|
14733
|
+
}
|
|
14734
|
+
/**
|
|
14735
|
+
* Returns the plain text of the line the cursor is on, up to the cursor.
|
|
14736
|
+
* @returns {{ text: string, range: Range, lineNode: Node } | null}
|
|
14737
|
+
*/
|
|
14738
|
+
_getLineContext() {
|
|
14739
|
+
const sel = window.getSelection();
|
|
14740
|
+
if (!sel || !sel.rangeCount) return null;
|
|
14741
|
+
const range = sel.getRangeAt(0);
|
|
14742
|
+
if (!range.collapsed) return null;
|
|
14743
|
+
const editable = this.context.layoutInfo.editable;
|
|
14744
|
+
if (!editable.contains(range.startContainer)) return null;
|
|
14745
|
+
let node = range.startContainer;
|
|
14746
|
+
while (node && node !== editable && !this._isBlock(node)) node = node.parentNode;
|
|
14747
|
+
if (!node || node === editable) node = range.startContainer;
|
|
14748
|
+
const tmpRange = document.createRange();
|
|
14749
|
+
tmpRange.setStart(node, 0);
|
|
14750
|
+
tmpRange.setEnd(range.startContainer, range.startOffset);
|
|
14751
|
+
return {
|
|
14752
|
+
text: tmpRange.toString(),
|
|
14753
|
+
range,
|
|
14754
|
+
lineNode: node
|
|
14755
|
+
};
|
|
14756
|
+
}
|
|
14757
|
+
_isBlock(node) {
|
|
14758
|
+
if (node.nodeType !== Node.ELEMENT_NODE) return false;
|
|
14759
|
+
const display = window.getComputedStyle(node).display;
|
|
14760
|
+
return display === "block" || display === "list-item" || display === "table-cell";
|
|
14761
|
+
}
|
|
14762
|
+
/** Applies block rule on Space key. Returns true if a rule fired. */
|
|
14763
|
+
_applyBlockRule() {
|
|
14764
|
+
const ctx = this._getLineContext();
|
|
14765
|
+
if (!ctx) return false;
|
|
14766
|
+
const { text } = ctx;
|
|
14767
|
+
const blockPatterns = [
|
|
14768
|
+
{
|
|
14769
|
+
re: /^(#{1,3})$/,
|
|
14770
|
+
handler: (m) => this._convertToHeading(m[1].length)
|
|
14771
|
+
},
|
|
14772
|
+
{
|
|
14773
|
+
re: /^>$/,
|
|
14774
|
+
handler: () => this._convertToBlockquote()
|
|
14775
|
+
},
|
|
14776
|
+
{
|
|
14777
|
+
re: /^[-*]$/,
|
|
14778
|
+
handler: () => this._convertToList("ul")
|
|
14779
|
+
},
|
|
14780
|
+
{
|
|
14781
|
+
re: /^1\.$/,
|
|
14782
|
+
handler: () => this._convertToList("ol")
|
|
14783
|
+
},
|
|
14784
|
+
{
|
|
14785
|
+
re: /^\[ \]$/,
|
|
14786
|
+
handler: () => this._convertToChecklist()
|
|
14787
|
+
}
|
|
14788
|
+
];
|
|
14789
|
+
for (const { re, handler } of blockPatterns) {
|
|
14790
|
+
const m = text.match(re);
|
|
14791
|
+
if (m) {
|
|
14792
|
+
handler(m);
|
|
14793
|
+
return true;
|
|
14794
|
+
}
|
|
14795
|
+
}
|
|
14796
|
+
return false;
|
|
14797
|
+
}
|
|
14798
|
+
/** Applies block rule on Enter key (---, ```). Returns true if a rule fired. */
|
|
14799
|
+
_applyEnterRule() {
|
|
14800
|
+
const ctx = this._getLineContext();
|
|
14801
|
+
if (!ctx) return false;
|
|
14802
|
+
const { text } = ctx;
|
|
14803
|
+
if (/^-{3,}$/.test(text)) {
|
|
14804
|
+
this._convertToHr();
|
|
14805
|
+
return true;
|
|
14806
|
+
}
|
|
14807
|
+
if (/^`{3}/.test(text)) {
|
|
14808
|
+
this._convertToCodeBlock();
|
|
14809
|
+
return true;
|
|
14810
|
+
}
|
|
14811
|
+
return false;
|
|
14812
|
+
}
|
|
14813
|
+
_selectLineAndDelete() {
|
|
14814
|
+
const sel = window.getSelection();
|
|
14815
|
+
if (!sel || !sel.rangeCount) return;
|
|
14816
|
+
const range = sel.getRangeAt(0);
|
|
14817
|
+
const startRange = document.createRange();
|
|
14818
|
+
startRange.setStart(range.startContainer.parentNode || range.startContainer, 0);
|
|
14819
|
+
startRange.setEnd(range.startContainer, range.startOffset);
|
|
14820
|
+
startRange.deleteContents();
|
|
14821
|
+
}
|
|
14822
|
+
_convertToHeading(level) {
|
|
14823
|
+
this._selectLineAndDelete();
|
|
14824
|
+
document.execCommand("formatBlock", false, `h${level}`);
|
|
14825
|
+
this.context.triggerEvent("change", this.context.getHTML());
|
|
14826
|
+
}
|
|
14827
|
+
_convertToBlockquote() {
|
|
14828
|
+
this._selectLineAndDelete();
|
|
14829
|
+
document.execCommand("formatBlock", false, "blockquote");
|
|
14830
|
+
this.context.triggerEvent("change", this.context.getHTML());
|
|
14831
|
+
}
|
|
14832
|
+
_convertToList(type) {
|
|
14833
|
+
this._selectLineAndDelete();
|
|
14834
|
+
document.execCommand(type === "ul" ? "insertUnorderedList" : "insertOrderedList");
|
|
14835
|
+
this.context.triggerEvent("change", this.context.getHTML());
|
|
14836
|
+
}
|
|
14837
|
+
_convertToChecklist() {
|
|
14838
|
+
this._selectLineAndDelete();
|
|
14839
|
+
this.context.invoke("editor.checklist");
|
|
14840
|
+
this.context.triggerEvent("change", this.context.getHTML());
|
|
14841
|
+
}
|
|
14842
|
+
_convertToHr() {
|
|
14843
|
+
this._selectLineAndDelete();
|
|
14844
|
+
this.context.invoke("editor.insertHR");
|
|
14845
|
+
this.context.triggerEvent("change", this.context.getHTML());
|
|
14846
|
+
}
|
|
14847
|
+
_convertToCodeBlock() {
|
|
14848
|
+
this._selectLineAndDelete();
|
|
14849
|
+
document.execCommand("formatBlock", false, "pre");
|
|
14850
|
+
this.context.triggerEvent("change", this.context.getHTML());
|
|
14851
|
+
}
|
|
14852
|
+
_onInput() {
|
|
14853
|
+
const sel = window.getSelection();
|
|
14854
|
+
if (!sel || !sel.rangeCount) return;
|
|
14855
|
+
const range = sel.getRangeAt(0);
|
|
14856
|
+
if (!range.collapsed) return;
|
|
14857
|
+
if (!this.context.layoutInfo.editable.contains(range.startContainer)) return;
|
|
14858
|
+
const node = range.startContainer;
|
|
14859
|
+
if (node.nodeType !== Node.TEXT_NODE) return;
|
|
14860
|
+
const text = node.textContent;
|
|
14861
|
+
const offset = range.startOffset;
|
|
14862
|
+
const inlineRules = [
|
|
14863
|
+
{
|
|
14864
|
+
re: /\*\*(.+?)\*\*$/,
|
|
14865
|
+
tag: "strong"
|
|
14866
|
+
},
|
|
14867
|
+
{
|
|
14868
|
+
re: /(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)$/,
|
|
14869
|
+
tag: "em"
|
|
14870
|
+
},
|
|
14871
|
+
{
|
|
14872
|
+
re: /~~(.+?)~~$/,
|
|
14873
|
+
tag: "s"
|
|
14874
|
+
},
|
|
14875
|
+
{
|
|
14876
|
+
re: /`([^`]+)`$/,
|
|
14877
|
+
tag: "code"
|
|
14878
|
+
}
|
|
14879
|
+
];
|
|
14880
|
+
const upToCursor = text.slice(0, offset);
|
|
14881
|
+
for (const { re, tag } of inlineRules) {
|
|
14882
|
+
const m = upToCursor.match(re);
|
|
14883
|
+
if (!m) continue;
|
|
14884
|
+
const matchStart = upToCursor.length - m[0].length;
|
|
14885
|
+
const matchEnd = offset;
|
|
14886
|
+
const innerText = m[1];
|
|
14887
|
+
const before = text.slice(0, matchStart);
|
|
14888
|
+
const after = text.slice(matchEnd);
|
|
14889
|
+
const el = document.createElement(tag);
|
|
14890
|
+
el.textContent = innerText;
|
|
14891
|
+
const beforeNode = document.createTextNode(before);
|
|
14892
|
+
const afterNode = document.createTextNode("" + after);
|
|
14893
|
+
const parent = node.parentNode;
|
|
14894
|
+
parent.insertBefore(beforeNode, node);
|
|
14895
|
+
parent.insertBefore(el, node);
|
|
14896
|
+
parent.insertBefore(afterNode, node);
|
|
14897
|
+
parent.removeChild(node);
|
|
14898
|
+
const newRange = document.createRange();
|
|
14899
|
+
newRange.setStart(afterNode, 1);
|
|
14900
|
+
newRange.collapse(true);
|
|
14901
|
+
sel.removeAllRanges();
|
|
14902
|
+
sel.addRange(newRange);
|
|
14903
|
+
this.context.triggerEvent("change", this.context.getHTML());
|
|
14904
|
+
break;
|
|
14905
|
+
}
|
|
14906
|
+
}
|
|
14907
|
+
};
|
|
14908
|
+
//#endregion
|
|
14909
|
+
//#region src/js/module/BubbleToolbar.js
|
|
14910
|
+
/**
|
|
14911
|
+
* BubbleToolbar.js — A mini floating toolbar that appears above the current
|
|
14912
|
+
* text selection, allowing quick access to common formatting actions without
|
|
14913
|
+
* reaching for the main toolbar.
|
|
14914
|
+
*
|
|
14915
|
+
* Activated when `bubbleToolbar: true`. The set of visible buttons is
|
|
14916
|
+
* controlled by `bubbleToolbarItems` (array of button name strings).
|
|
14917
|
+
*
|
|
14918
|
+
* Built-in names: 'bold', 'italic', 'underline', 'strikethrough',
|
|
14919
|
+
* 'link', 'foreColor', 'removeFormat', 'inlineCode'.
|
|
14920
|
+
* Any name not found in the built-in map is silently ignored.
|
|
14921
|
+
*/
|
|
14922
|
+
var _S = "stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"";
|
|
14923
|
+
var _svg = (p) => `<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" ${_S} style="display:block">${p}</svg>`;
|
|
14924
|
+
var _ICONS = {
|
|
14925
|
+
bold: _svg("<path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"/>"),
|
|
14926
|
+
italic: _svg("<line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"/><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"/><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"/>"),
|
|
14927
|
+
underline: _svg("<path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"/><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"/>"),
|
|
14928
|
+
strikethrough: _svg("<path d=\"M17.3 12H6.7\"/><path d=\"M10 6.5C10 5.1 11.1 4 12.5 4c1.4 0 2.5 1.1 2.5 2.5 0 .8-.4 1.5-1 2\"/><path d=\"M14 17.5C14 19 12.9 20 11.5 20 10.1 20 9 18.9 9 17.5c0-.8.4-1.5 1-2\"/>"),
|
|
14929
|
+
link: _svg("<path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>"),
|
|
14930
|
+
foreColor: _svg("<path d=\"M4 20L12 4L20 20\"/><line x1=\"7.5\" y1=\"14\" x2=\"16.5\" y2=\"14\"/>"),
|
|
14931
|
+
removeFormat: _svg("<path d=\"m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21\"/><path d=\"M22 21H7\"/><path d=\"m5 11 9 9\"/>"),
|
|
14932
|
+
inlineCode: _svg("<path d=\"M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1\"/><path d=\"M16 3h1a2 2 0 0 1 2 2v5c0 1.1.9 2 2 2a2 2 0 0 1-2 2v5a2 2 0 0 1-2 2h-1\"/>")
|
|
14933
|
+
};
|
|
14934
|
+
var _ACTIONS = {
|
|
14935
|
+
bold: (ctx) => ctx.invoke("editor.bold"),
|
|
14936
|
+
italic: (ctx) => ctx.invoke("editor.italic"),
|
|
14937
|
+
underline: (ctx) => ctx.invoke("editor.underline"),
|
|
14938
|
+
strikethrough: (ctx) => ctx.invoke("editor.strikethrough"),
|
|
14939
|
+
link: (ctx) => ctx.invoke("linkDialog.show"),
|
|
14940
|
+
foreColor: (ctx) => {
|
|
14941
|
+
const color = window.prompt("Text color (hex or name):", "#000000");
|
|
14942
|
+
if (color) ctx.invoke("editor.foreColor", color);
|
|
14943
|
+
},
|
|
14944
|
+
removeFormat: (ctx) => ctx.invoke("editor.removeFormat"),
|
|
14945
|
+
inlineCode: (ctx) => ctx.invoke("editor.inlineCode")
|
|
14946
|
+
};
|
|
14947
|
+
var _ACTIVE = {
|
|
14948
|
+
bold: () => document.queryCommandState("bold"),
|
|
14949
|
+
italic: () => document.queryCommandState("italic"),
|
|
14950
|
+
underline: () => document.queryCommandState("underline"),
|
|
14951
|
+
strikethrough: () => document.queryCommandState("strikeThrough")
|
|
14952
|
+
};
|
|
14953
|
+
var BubbleToolbar = class {
|
|
14954
|
+
/** @param {import('../Context.js').Context} context */
|
|
14955
|
+
constructor(context) {
|
|
14956
|
+
this.context = context;
|
|
14957
|
+
this.options = context.options;
|
|
14958
|
+
/** @type {HTMLElement|null} */
|
|
14959
|
+
this._el = null;
|
|
14960
|
+
this._visible = false;
|
|
14961
|
+
this._rafId = null;
|
|
14962
|
+
this._contextMenuOpen = false;
|
|
14963
|
+
this._disposers = [];
|
|
14964
|
+
this._onSelectionChange = this._onSelectionChange.bind(this);
|
|
14965
|
+
this._onMousedown = this._onMousedown.bind(this);
|
|
14966
|
+
this._onKeydown = this._onKeydown.bind(this);
|
|
14967
|
+
this._onContextMenu = this._onContextMenu.bind(this);
|
|
14968
|
+
}
|
|
14969
|
+
initialize() {
|
|
14970
|
+
if (!this.options.bubbleToolbar) return this;
|
|
14971
|
+
this._build();
|
|
14972
|
+
const d1 = on(document, "selectionchange", this._onSelectionChange);
|
|
14973
|
+
const d2 = on(document, "mousedown", this._onMousedown);
|
|
14974
|
+
const d3 = on(document, "keydown", this._onKeydown);
|
|
14975
|
+
const d4 = on(document, "contextmenu", this._onContextMenu);
|
|
14976
|
+
const d5 = this.context.on("contextMenu:show", () => {
|
|
14977
|
+
this._contextMenuOpen = true;
|
|
14978
|
+
this._hide();
|
|
14979
|
+
});
|
|
14980
|
+
const d6 = this.context.on("contextMenu:hide", () => {
|
|
14981
|
+
this._contextMenuOpen = false;
|
|
14982
|
+
});
|
|
14983
|
+
this._disposers.push(d1, d2, d3, d4, d5, d6);
|
|
14984
|
+
return this;
|
|
14985
|
+
}
|
|
14986
|
+
destroy() {
|
|
14987
|
+
if (this._el && this._el.parentNode) this._el.parentNode.removeChild(this._el);
|
|
14988
|
+
this._el = null;
|
|
14989
|
+
this._disposers.forEach((d) => d());
|
|
14990
|
+
this._disposers = [];
|
|
14991
|
+
cancelAnimationFrame(this._rafId);
|
|
14992
|
+
}
|
|
14993
|
+
_build() {
|
|
14994
|
+
const el = document.createElement("div");
|
|
14995
|
+
el.className = "an-bubble-toolbar";
|
|
14996
|
+
el.setAttribute("role", "toolbar");
|
|
14997
|
+
el.setAttribute("aria-label", "Formatting");
|
|
14998
|
+
const items = this.options.bubbleToolbarItems || [
|
|
14999
|
+
"bold",
|
|
15000
|
+
"italic",
|
|
15001
|
+
"underline",
|
|
15002
|
+
"link",
|
|
15003
|
+
"foreColor",
|
|
15004
|
+
"removeFormat"
|
|
15005
|
+
];
|
|
15006
|
+
for (const name of items) {
|
|
15007
|
+
if (!_ICONS[name] || !_ACTIONS[name]) continue;
|
|
15008
|
+
const btn = document.createElement("button");
|
|
15009
|
+
btn.type = "button";
|
|
15010
|
+
btn.className = "an-bubble-btn";
|
|
15011
|
+
btn.dataset.name = name;
|
|
15012
|
+
btn.setAttribute("aria-label", name);
|
|
15013
|
+
btn.innerHTML = _ICONS[name];
|
|
15014
|
+
btn.addEventListener("mousedown", (e) => {
|
|
15015
|
+
e.preventDefault();
|
|
15016
|
+
});
|
|
15017
|
+
btn.addEventListener("click", (e) => {
|
|
15018
|
+
e.preventDefault();
|
|
15019
|
+
e.stopPropagation();
|
|
15020
|
+
this.context.invoke("editor.focus");
|
|
15021
|
+
_ACTIONS[name](this.context);
|
|
15022
|
+
this.context.invoke("editor.afterCommand");
|
|
15023
|
+
this._syncActive();
|
|
15024
|
+
});
|
|
15025
|
+
el.appendChild(btn);
|
|
15026
|
+
}
|
|
15027
|
+
document.body.appendChild(el);
|
|
15028
|
+
this._el = el;
|
|
15029
|
+
}
|
|
15030
|
+
_show(rect) {
|
|
15031
|
+
if (!this._el) return;
|
|
15032
|
+
const el = this._el;
|
|
15033
|
+
el.style.visibility = "hidden";
|
|
15034
|
+
el.style.display = "flex";
|
|
15035
|
+
const bw = el.offsetWidth;
|
|
15036
|
+
const bh = el.offsetHeight;
|
|
15037
|
+
const gap = 8;
|
|
15038
|
+
let left = rect.left + rect.width / 2 - bw / 2;
|
|
15039
|
+
let top = rect.top - bh - gap;
|
|
15040
|
+
left = Math.max(8, Math.min(left, window.innerWidth - bw - 8));
|
|
15041
|
+
if (top < 8) top = rect.bottom + gap;
|
|
15042
|
+
el.style.top = `${top}px`;
|
|
15043
|
+
el.style.left = `${left}px`;
|
|
15044
|
+
el.style.visibility = "";
|
|
15045
|
+
this._syncActive();
|
|
15046
|
+
this._visible = true;
|
|
15047
|
+
}
|
|
15048
|
+
_hide() {
|
|
15049
|
+
if (!this._el) return;
|
|
15050
|
+
this._el.style.display = "none";
|
|
15051
|
+
this._visible = false;
|
|
15052
|
+
}
|
|
15053
|
+
_syncActive() {
|
|
15054
|
+
if (!this._el) return;
|
|
15055
|
+
this._el.querySelectorAll(".an-bubble-btn").forEach((btn) => {
|
|
15056
|
+
const activeFn = _ACTIVE[btn.dataset.name];
|
|
15057
|
+
btn.classList.toggle("an-active", !!(activeFn && activeFn()));
|
|
15058
|
+
});
|
|
15059
|
+
}
|
|
15060
|
+
_onSelectionChange() {
|
|
15061
|
+
cancelAnimationFrame(this._rafId);
|
|
15062
|
+
this._rafId = requestAnimationFrame(() => {
|
|
15063
|
+
if (this._contextMenuOpen) return;
|
|
15064
|
+
const sel = window.getSelection();
|
|
15065
|
+
if (!sel || sel.isCollapsed || !sel.rangeCount) {
|
|
15066
|
+
this._hide();
|
|
15067
|
+
return;
|
|
15068
|
+
}
|
|
15069
|
+
if (!this.context.layoutInfo.editable.contains(sel.anchorNode)) {
|
|
15070
|
+
this._hide();
|
|
15071
|
+
return;
|
|
15072
|
+
}
|
|
15073
|
+
if (this.context.options.readOnly) {
|
|
15074
|
+
this._hide();
|
|
15075
|
+
return;
|
|
15076
|
+
}
|
|
15077
|
+
const rect = sel.getRangeAt(0).getBoundingClientRect();
|
|
15078
|
+
if (!rect || rect.width === 0) {
|
|
15079
|
+
this._hide();
|
|
15080
|
+
return;
|
|
15081
|
+
}
|
|
15082
|
+
this._show(rect);
|
|
15083
|
+
});
|
|
15084
|
+
}
|
|
15085
|
+
_onMousedown(e) {
|
|
15086
|
+
if (!this._visible) return;
|
|
15087
|
+
if (this._el && this._el.contains(e.target)) return;
|
|
15088
|
+
if (this.context.layoutInfo.editable.contains(e.target)) return;
|
|
15089
|
+
this._hide();
|
|
15090
|
+
}
|
|
15091
|
+
_onKeydown(e) {
|
|
15092
|
+
if (e.key === "Escape" && this._visible) this._hide();
|
|
15093
|
+
}
|
|
15094
|
+
_onContextMenu() {
|
|
15095
|
+
this._hide();
|
|
15096
|
+
}
|
|
15097
|
+
};
|
|
15098
|
+
//#endregion
|
|
15099
|
+
//#region src/js/module/Mention.js
|
|
15100
|
+
/**
|
|
15101
|
+
* Mention.js — @mention autocomplete support.
|
|
15102
|
+
*
|
|
15103
|
+
* Activated when `mention.onSearch` option is provided.
|
|
15104
|
+
*
|
|
15105
|
+
* When the user types the trigger character (default `@`) followed by at least
|
|
15106
|
+
* `mention.minChars` characters, `onSearch(query, callback)` is called.
|
|
15107
|
+
* The callback receives an array of `{ id, label, avatar? }` items which are
|
|
15108
|
+
* rendered in a floating dropdown. Selecting an item inserts a non-editable
|
|
15109
|
+
* mention chip and fires `onInsert` (if provided) to override the default HTML.
|
|
15110
|
+
*
|
|
15111
|
+
* Options shape (passed as `mention` option object):
|
|
15112
|
+
* {
|
|
15113
|
+
* trigger: '@',
|
|
15114
|
+
* minChars: 1,
|
|
15115
|
+
* maxResults: 8,
|
|
15116
|
+
* debounce: 200,
|
|
15117
|
+
* onSearch: (query, callback) => void,
|
|
15118
|
+
* onInsert: (item) => string | null,
|
|
15119
|
+
* mentionClass: 'an-mention',
|
|
15120
|
+
* allowSpaces: false,
|
|
15121
|
+
* }
|
|
15122
|
+
*/
|
|
15123
|
+
var Mention = class {
|
|
15124
|
+
/** @param {import('../Context.js').Context} context */
|
|
15125
|
+
constructor(context) {
|
|
15126
|
+
this.context = context;
|
|
15127
|
+
/** @type {HTMLElement|null} */
|
|
15128
|
+
this._dropdown = null;
|
|
15129
|
+
/** @type {string} */
|
|
15130
|
+
this._query = "";
|
|
15131
|
+
/** @type {number|null} */
|
|
15132
|
+
this._debounceTimer = null;
|
|
15133
|
+
/** @type {number} current highlighted index */
|
|
15134
|
+
this._activeIndex = -1;
|
|
15135
|
+
/** @type {Array<{id, label, avatar?}>} */
|
|
15136
|
+
this._items = [];
|
|
15137
|
+
/** @type {boolean} */
|
|
15138
|
+
this._open = false;
|
|
15139
|
+
/** Position of trigger character in the text node */
|
|
15140
|
+
this._triggerNode = null;
|
|
15141
|
+
this._triggerOffset = 0;
|
|
15142
|
+
/** @type {DOMRect|null} Caret rect captured synchronously during input event */
|
|
15143
|
+
this._caretRect = null;
|
|
15144
|
+
this._disposers = [];
|
|
15145
|
+
}
|
|
15146
|
+
initialize() {
|
|
15147
|
+
const cfg = this.context.options.mention;
|
|
15148
|
+
if (!cfg || typeof cfg.onSearch !== "function") return this;
|
|
15149
|
+
this._cfg = {
|
|
15150
|
+
trigger: cfg.trigger || "@",
|
|
15151
|
+
minChars: cfg.minChars ?? 0,
|
|
15152
|
+
maxResults: cfg.maxResults ?? 8,
|
|
15153
|
+
debounce: cfg.debounce ?? 200,
|
|
15154
|
+
onSearch: cfg.onSearch,
|
|
15155
|
+
onInsert: cfg.onInsert || null,
|
|
15156
|
+
mentionClass: cfg.mentionClass || "an-mention",
|
|
15157
|
+
allowSpaces: cfg.allowSpaces || false
|
|
15158
|
+
};
|
|
15159
|
+
this._buildDropdown();
|
|
15160
|
+
const editable = this.context.layoutInfo.editable;
|
|
15161
|
+
const d1 = on(editable, "keydown", (e) => this._onKeydown(e));
|
|
15162
|
+
const d2 = on(editable, "input", () => this._onInput());
|
|
15163
|
+
const d3 = on(document, "click", (e) => this._onDocClick(e));
|
|
15164
|
+
this._disposers.push(d1, d2, d3);
|
|
15165
|
+
return this;
|
|
15166
|
+
}
|
|
15167
|
+
destroy() {
|
|
15168
|
+
clearTimeout(this._debounceTimer);
|
|
15169
|
+
if (this._dropdown && this._dropdown.parentNode) this._dropdown.parentNode.removeChild(this._dropdown);
|
|
15170
|
+
this._dropdown = null;
|
|
15171
|
+
this._disposers.forEach((d) => d());
|
|
15172
|
+
this._disposers = [];
|
|
15173
|
+
}
|
|
15174
|
+
_buildDropdown() {
|
|
15175
|
+
const el = document.createElement("div");
|
|
15176
|
+
el.className = "an-mention-dropdown";
|
|
15177
|
+
el.setAttribute("role", "listbox");
|
|
15178
|
+
document.body.appendChild(el);
|
|
15179
|
+
this._dropdown = el;
|
|
15180
|
+
}
|
|
15181
|
+
_renderItems(items) {
|
|
15182
|
+
const dd = this._dropdown;
|
|
15183
|
+
dd.innerHTML = "";
|
|
15184
|
+
this._items = items.slice(0, this._cfg.maxResults);
|
|
15185
|
+
this._activeIndex = this._items.length > 0 ? 0 : -1;
|
|
15186
|
+
this._items.forEach((item, i) => {
|
|
15187
|
+
const li = document.createElement("div");
|
|
15188
|
+
li.className = "an-mention-item";
|
|
15189
|
+
li.setAttribute("role", "option");
|
|
15190
|
+
li.dataset.index = i;
|
|
15191
|
+
if (item.avatar) {
|
|
15192
|
+
const img = document.createElement("img");
|
|
15193
|
+
img.src = item.avatar;
|
|
15194
|
+
img.className = "an-mention-avatar";
|
|
15195
|
+
img.alt = "";
|
|
15196
|
+
li.appendChild(img);
|
|
15197
|
+
}
|
|
15198
|
+
const label = document.createElement("span");
|
|
15199
|
+
label.textContent = item.label;
|
|
15200
|
+
li.appendChild(label);
|
|
15201
|
+
li.addEventListener("mousedown", (e) => e.preventDefault());
|
|
15202
|
+
li.addEventListener("click", () => this._select(i));
|
|
15203
|
+
dd.appendChild(li);
|
|
15204
|
+
});
|
|
15205
|
+
this._highlightItem(this._activeIndex);
|
|
15206
|
+
}
|
|
15207
|
+
_highlightItem(index) {
|
|
15208
|
+
if (!this._dropdown) return;
|
|
15209
|
+
this._dropdown.querySelectorAll(".an-mention-item").forEach((el, i) => {
|
|
15210
|
+
el.classList.toggle("an-mention-active", i === index);
|
|
15211
|
+
});
|
|
15212
|
+
this._activeIndex = index;
|
|
15213
|
+
}
|
|
15214
|
+
_positionDropdown() {
|
|
15215
|
+
const dd = this._dropdown;
|
|
15216
|
+
const rect = this._caretRect;
|
|
15217
|
+
if (!rect || rect.height === 0) return;
|
|
15218
|
+
dd.style.visibility = "hidden";
|
|
15219
|
+
dd.style.display = "block";
|
|
15220
|
+
const ddh = dd.offsetHeight;
|
|
15221
|
+
const ddw = dd.offsetWidth;
|
|
15222
|
+
let top = rect.bottom + 4;
|
|
15223
|
+
let left = rect.left;
|
|
15224
|
+
if (rect.bottom + ddh + 8 > window.innerHeight) top = rect.top - ddh - 4;
|
|
15225
|
+
left = Math.max(8, Math.min(left, window.innerWidth - ddw - 8));
|
|
15226
|
+
dd.style.top = `${top}px`;
|
|
15227
|
+
dd.style.left = `${left}px`;
|
|
15228
|
+
dd.style.visibility = "";
|
|
15229
|
+
}
|
|
15230
|
+
_showDropdown() {
|
|
15231
|
+
this._open = true;
|
|
15232
|
+
this._positionDropdown();
|
|
15233
|
+
}
|
|
15234
|
+
_hideDropdown() {
|
|
15235
|
+
if (this._dropdown) this._dropdown.style.display = "none";
|
|
15236
|
+
this._open = false;
|
|
15237
|
+
this._items = [];
|
|
15238
|
+
this._activeIndex = -1;
|
|
15239
|
+
this._triggerNode = null;
|
|
15240
|
+
this._caretRect = null;
|
|
15241
|
+
this._query = "";
|
|
15242
|
+
}
|
|
15243
|
+
/**
|
|
15244
|
+
* Captures the caret rect synchronously during the input event.
|
|
15245
|
+
* Must be called while the DOM event is still live — getClientRects() on a
|
|
15246
|
+
* collapsed range is reliable at this point but often empty inside async callbacks.
|
|
15247
|
+
*/
|
|
15248
|
+
_captureCaretRect() {
|
|
15249
|
+
if (this._triggerNode && this._triggerNode.isConnected) try {
|
|
15250
|
+
const r = document.createRange();
|
|
15251
|
+
const end = Math.min(this._triggerOffset + 1, this._triggerNode.textContent.length);
|
|
15252
|
+
r.setStart(this._triggerNode, this._triggerOffset);
|
|
15253
|
+
r.setEnd(this._triggerNode, end);
|
|
15254
|
+
const candidate = r.getBoundingClientRect();
|
|
15255
|
+
if (candidate.height > 0) {
|
|
15256
|
+
this._caretRect = candidate;
|
|
15257
|
+
return;
|
|
15258
|
+
}
|
|
15259
|
+
} catch (_) {}
|
|
15260
|
+
const sel = window.getSelection();
|
|
15261
|
+
if (!sel || !sel.rangeCount) return;
|
|
15262
|
+
const rects = sel.getRangeAt(0).getClientRects();
|
|
15263
|
+
if (rects.length > 0) this._caretRect = rects[rects.length - 1];
|
|
15264
|
+
}
|
|
15265
|
+
_getQueryAtCursor() {
|
|
15266
|
+
const sel = window.getSelection();
|
|
15267
|
+
if (!sel || !sel.rangeCount) return null;
|
|
15268
|
+
const range = sel.getRangeAt(0);
|
|
15269
|
+
if (!range.collapsed) return null;
|
|
15270
|
+
const node = range.startContainer;
|
|
15271
|
+
if (node.nodeType !== Node.TEXT_NODE) return null;
|
|
15272
|
+
const text = node.textContent.slice(0, range.startOffset);
|
|
15273
|
+
const trigger = this._cfg.trigger;
|
|
15274
|
+
const triggerIdx = text.lastIndexOf(trigger);
|
|
15275
|
+
if (triggerIdx === -1) return null;
|
|
15276
|
+
const afterTrigger = text.slice(triggerIdx + trigger.length);
|
|
15277
|
+
if (!this._cfg.allowSpaces && /\s/.test(afterTrigger)) return null;
|
|
15278
|
+
if (afterTrigger.length < this._cfg.minChars) return null;
|
|
15279
|
+
this._triggerNode = node;
|
|
15280
|
+
this._triggerOffset = triggerIdx;
|
|
15281
|
+
return afterTrigger;
|
|
15282
|
+
}
|
|
15283
|
+
_onInput() {
|
|
15284
|
+
if (!this._cfg) return;
|
|
15285
|
+
const query = this._getQueryAtCursor();
|
|
15286
|
+
if (query === null) {
|
|
15287
|
+
this._hideDropdown();
|
|
15288
|
+
return;
|
|
15289
|
+
}
|
|
15290
|
+
this._captureCaretRect();
|
|
15291
|
+
this._query = query;
|
|
15292
|
+
clearTimeout(this._debounceTimer);
|
|
15293
|
+
this._debounceTimer = setTimeout(() => {
|
|
15294
|
+
this._cfg.onSearch(this._query, (items) => {
|
|
15295
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
15296
|
+
this._hideDropdown();
|
|
15297
|
+
return;
|
|
15298
|
+
}
|
|
15299
|
+
this._renderItems(items);
|
|
15300
|
+
this._showDropdown();
|
|
15301
|
+
});
|
|
15302
|
+
}, this._cfg.debounce);
|
|
15303
|
+
}
|
|
15304
|
+
_onKeydown(e) {
|
|
15305
|
+
if (!this._cfg || !this._open) return;
|
|
15306
|
+
if (e.key === "ArrowDown") {
|
|
15307
|
+
e.preventDefault();
|
|
15308
|
+
const next = (this._activeIndex + 1) % this._items.length;
|
|
15309
|
+
this._highlightItem(next);
|
|
15310
|
+
} else if (e.key === "ArrowUp") {
|
|
15311
|
+
e.preventDefault();
|
|
15312
|
+
const prev = (this._activeIndex - 1 + this._items.length) % this._items.length;
|
|
15313
|
+
this._highlightItem(prev);
|
|
15314
|
+
} else if (e.key === "Enter" || e.key === "Tab") {
|
|
15315
|
+
if (this._activeIndex >= 0) {
|
|
15316
|
+
e.preventDefault();
|
|
15317
|
+
this._select(this._activeIndex);
|
|
15318
|
+
}
|
|
15319
|
+
} else if (e.key === "Escape") this._hideDropdown();
|
|
15320
|
+
}
|
|
15321
|
+
_onDocClick(e) {
|
|
15322
|
+
if (!this._open) return;
|
|
15323
|
+
if (this._dropdown && this._dropdown.contains(e.target)) return;
|
|
15324
|
+
this._hideDropdown();
|
|
15325
|
+
}
|
|
15326
|
+
_select(index) {
|
|
15327
|
+
const item = this._items[index];
|
|
15328
|
+
if (!item) return;
|
|
15329
|
+
if (this._triggerNode) {
|
|
15330
|
+
const node = this._triggerNode;
|
|
15331
|
+
node.textContent = node.textContent.slice(0, this._triggerOffset) + node.textContent.slice(this._triggerOffset + this._cfg.trigger.length + this._query.length);
|
|
15332
|
+
const sel = window.getSelection();
|
|
15333
|
+
const range = document.createRange();
|
|
15334
|
+
range.setStart(node, this._triggerOffset);
|
|
15335
|
+
range.collapse(true);
|
|
15336
|
+
sel.removeAllRanges();
|
|
15337
|
+
sel.addRange(range);
|
|
15338
|
+
}
|
|
15339
|
+
let html;
|
|
15340
|
+
if (typeof this._cfg.onInsert === "function") html = this._cfg.onInsert(item);
|
|
15341
|
+
if (!html) html = `<span class="${this._cfg.mentionClass}" data-mention-id="${item.id}" contenteditable="false">@${item.label}</span>`;
|
|
15342
|
+
this.context.invoke("editor.insertHTML", html + "​");
|
|
15343
|
+
this._hideDropdown();
|
|
15344
|
+
this.context.triggerEvent("change", this.context.getHTML());
|
|
15345
|
+
}
|
|
15346
|
+
};
|
|
15347
|
+
//#endregion
|
|
11866
15348
|
//#region src/js/Context.js
|
|
11867
15349
|
/**
|
|
11868
15350
|
* Context.js - Central hub for the editor instance
|
|
@@ -11879,6 +15361,8 @@ var Context = class {
|
|
|
11879
15361
|
constructor(targetEl, userOptions = {}) {
|
|
11880
15362
|
this.targetEl = targetEl;
|
|
11881
15363
|
this.options = mergeDeep(defaultOptions, userOptions);
|
|
15364
|
+
/** @type {import('./i18n/index.js').AsnLocale} */
|
|
15365
|
+
this.locale = resolveLocale(this.options.lang);
|
|
11882
15366
|
/** @type {{ container: HTMLElement, editable: HTMLElement, toolbar?: HTMLElement, statusbar?: HTMLElement }} */
|
|
11883
15367
|
this.layoutInfo = {};
|
|
11884
15368
|
/** @type {Map<string, Function[]>} */
|
|
@@ -11939,6 +15423,10 @@ var Context = class {
|
|
|
11939
15423
|
register("shortcutsDialog", ShortcutsDialog);
|
|
11940
15424
|
register("findReplace", FindReplace);
|
|
11941
15425
|
register("imageCropOverlay", ImageCropOverlay);
|
|
15426
|
+
register("autoSaveRestore", AutoSaveRestore);
|
|
15427
|
+
register("markdownShortcuts", MarkdownShortcuts);
|
|
15428
|
+
register("bubbleToolbar", BubbleToolbar);
|
|
15429
|
+
register("mention", Mention);
|
|
11942
15430
|
for (const [name, ModuleClass] of _customModules) register(name, ModuleClass);
|
|
11943
15431
|
}
|
|
11944
15432
|
/**
|
|
@@ -11970,7 +15458,9 @@ var Context = class {
|
|
|
11970
15458
|
if (this.options.autoSave && this.options.autoSaveKey) {
|
|
11971
15459
|
const d4 = this.on("change", () => {
|
|
11972
15460
|
try {
|
|
11973
|
-
|
|
15461
|
+
const key = this.options.autoSaveKey;
|
|
15462
|
+
localStorage.setItem(key, this.getHTML());
|
|
15463
|
+
localStorage.setItem(key + ":asrmeta", JSON.stringify({ savedAt: Date.now() }));
|
|
11974
15464
|
} catch (_) {}
|
|
11975
15465
|
});
|
|
11976
15466
|
this._disposers.push(d4);
|
|
@@ -12388,7 +15878,7 @@ var AutumnNote = {
|
|
|
12388
15878
|
registerModule(name, ModuleClass) {
|
|
12389
15879
|
_customModules.set(name, ModuleClass);
|
|
12390
15880
|
},
|
|
12391
|
-
version: "1.0.
|
|
15881
|
+
version: "1.0.9"
|
|
12392
15882
|
};
|
|
12393
15883
|
/**
|
|
12394
15884
|
* @param {string|Element|NodeList|Element[]} selector
|
|
@@ -12401,6 +15891,6 @@ function resolveElements(selector) {
|
|
|
12401
15891
|
return [];
|
|
12402
15892
|
}
|
|
12403
15893
|
//#endregion
|
|
12404
|
-
export { Context, ELEMENT_NODE, TEXT_NODE, WrappedRange, alignCenterBtn, alignJustifyBtn, alignLeftBtn, alignRightBtn, all, ancestors, any, backColorBtn, boldBtn, checklistBtn, children, chunk, clamp, closest, closestPara, codeviewBtn, collapsedRange, compose, createElement, currentRange, debounce, AutumnNote as default, defaultOptions, defaultToolbar, directionBtn, emojiBtn, env, findBtn, findReplaceBtn, first, flatten, fontFamilyBtn, fontSizeBtn, foreColorBtn, fromNativeRange, fullscreenBtn, groupBy, hrBtn, iconBtn, identity, imageBtn, indentBtn, initial, inlineCodeBtn, insertAfter, isAnchor, isEditable, isElement, isEmpty, isFunction, isImage, isInline, isInsideEditable, isKey, isLi, isList, isModifier, isNil, isPara, isPlainObject, isSelectionInside, isString, isTable, isText, isVoid, italicBtn, key, last, lineHeightBtn, linkBtn, mergeDeep, nextElement, nodeValue, olBtn, on, outdentBtn, outerHtml, paragraphStyleBtn, placeCaret, prevElement, printBtn, rangeFromElement, rect2bnd, redoBtn, remove, removeFormatBtn, sanitiseHTML, sanitiseUrl, shortcutsBtn, splitText, strikeBtn, subscriptBtn, superscriptBtn, tableBtn, tail, throttle, trapFocus, ulBtn, underlineBtn, undoBtn, unique, unwrap, videoBtn, withSavedRange, wrap };
|
|
15894
|
+
export { Context, ELEMENT_NODE, TEXT_NODE, WrappedRange, alignCenterBtn, alignJustifyBtn, alignLeftBtn, alignRightBtn, all, ancestors, any, backColorBtn, boldBtn, checklistBtn, children, chunk, clamp, closest, closestPara, codeviewBtn, collapsedRange, compose, createElement, currentRange, debounce, AutumnNote as default, defaultOptions, defaultToolbar, directionBtn, emojiBtn, env, findBtn, findReplaceBtn, first, flatten, fontFamilyBtn, fontSizeBtn, foreColorBtn, fromNativeRange, fullscreenBtn, groupBy, hrBtn, iconBtn, identity, imageBtn, indentBtn, initial, inlineCodeBtn, insertAfter, isAnchor, isEditable, isElement, isEmpty, isFunction, isImage, isInline, isInsideEditable, isKey, isLi, isList, isModifier, isNil, isPara, isPlainObject, isSelectionInside, isString, isTable, isText, isVoid, italicBtn, key, last, lineHeightBtn, linkBtn, locales, mergeDeep, nextElement, nodeValue, olBtn, on, outdentBtn, outerHtml, paragraphStyleBtn, placeCaret, prevElement, printBtn, rangeFromElement, rect2bnd, redoBtn, remove, removeFormatBtn, resolveLocale, sanitiseHTML, sanitiseUrl, shortcutsBtn, splitText, strikeBtn, subscriptBtn, superscriptBtn, tableBtn, tail, throttle, trapFocus, ulBtn, underlineBtn, undoBtn, unique, unwrap, videoBtn, withSavedRange, wrap };
|
|
12405
15895
|
|
|
12406
15896
|
//# sourceMappingURL=autumnnote.es.js.map
|