neiki-editor 3.0.1 → 3.0.3
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 +39 -26
- package/dist/neiki-editor.css +7 -1
- package/dist/neiki-editor.js +173 -10
- package/dist/neiki-editor.min.css +1 -1
- package/dist/neiki-editor.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="logo.png" alt="Neiki's Editor" width="400">
|
|
2
|
+
<img src="assets/logo.png" alt="Neiki's Editor" width="400">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">Neiki's Editor</h1>
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<img src="https://img.shields.io/badge/css-%23663399.svg?style=for-the-badge&logo=css&logoColor=white" alt="CSS">
|
|
12
12
|
<br>
|
|
13
13
|
<img src="https://img.shields.io/badge/License-AGPL--3.0-2563EB?style=for-the-badge&logo=open-source-initiative&logoColor=white&labelColor=000F15&logoWidth=20" alt="License">
|
|
14
|
-
<img src="https://img.shields.io/badge/Version-3.0.
|
|
14
|
+
<img src="https://img.shields.io/badge/Version-3.0.3-2563EB?style=for-the-badge&logo=semantic-release&logoColor=white&labelColor=000F15&logoWidth=20" alt="Version">
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
<p align="center">
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
<p align="center">
|
|
36
|
-
<img src="preview.png" alt="Neiki's Editor" width="900">
|
|
36
|
+
<img src="assets/preview.png" alt="Neiki's Editor" width="900">
|
|
37
37
|
</p>
|
|
38
38
|
|
|
39
39
|
---
|
|
40
40
|
|
|
41
|
-
**Live version:** [https://neikiri.dev/editor](https://neikiri.dev/editor)
|
|
41
|
+
**Live version:** [https://neikiri.dev/editor](https://neikiri.dev/editor) · **Documentation:** [Wiki](https://github.com/neikiri/neiki-editor/wiki)
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
@@ -62,7 +62,7 @@ Add this single line — CSS is included automatically, always the **latest vers
|
|
|
62
62
|
#### Pin a specific version
|
|
63
63
|
|
|
64
64
|
```html
|
|
65
|
-
<script src="https://cdn.neikiri.dev/neiki-editor/3.0.
|
|
65
|
+
<script src="https://cdn.neikiri.dev/neiki-editor/3.0.3/neiki-editor.min.js"></script>
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
#### Load CSS and JS separately
|
|
@@ -73,8 +73,8 @@ Add this single line — CSS is included automatically, always the **latest vers
|
|
|
73
73
|
<script src="https://cdn.neikiri.dev/neiki-editor/neiki-editor.js"></script>
|
|
74
74
|
|
|
75
75
|
<!-- Or pinned -->
|
|
76
|
-
<link rel="stylesheet" href="https://cdn.neikiri.dev/neiki-editor/3.0.
|
|
77
|
-
<script src="https://cdn.neikiri.dev/neiki-editor/3.0.
|
|
76
|
+
<link rel="stylesheet" href="https://cdn.neikiri.dev/neiki-editor/3.0.3/neiki-editor.css">
|
|
77
|
+
<script src="https://cdn.neikiri.dev/neiki-editor/3.0.3/neiki-editor.js"></script>
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
#### Alternative CDN — jsDelivr
|
|
@@ -84,15 +84,15 @@ Add this single line — CSS is included automatically, always the **latest vers
|
|
|
84
84
|
<script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@latest/dist/neiki-editor.min.js"></script>
|
|
85
85
|
|
|
86
86
|
<!-- Pinned -->
|
|
87
|
-
<script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@3.0.
|
|
87
|
+
<script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@3.0.3/dist/neiki-editor.min.js"></script>
|
|
88
88
|
|
|
89
89
|
<!-- Separate files (latest) -->
|
|
90
90
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@latest/dist/neiki-editor.css">
|
|
91
91
|
<script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@latest/dist/neiki-editor.js"></script>
|
|
92
92
|
|
|
93
93
|
<!-- Separate files (pinned) -->
|
|
94
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@3.0.
|
|
95
|
-
<script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@3.0.
|
|
94
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@3.0.3/dist/neiki-editor.css">
|
|
95
|
+
<script src="https://cdn.jsdelivr.net/gh/neikiri/neiki-editor@3.0.3/dist/neiki-editor.js"></script>
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
#### Package Manager
|
|
@@ -747,24 +747,37 @@ function NeikiEditorComponent({ value, onChange }) {
|
|
|
747
747
|
|
|
748
748
|
```
|
|
749
749
|
neiki-editor/
|
|
750
|
-
├──
|
|
751
|
-
│
|
|
752
|
-
│
|
|
753
|
-
│
|
|
754
|
-
│
|
|
750
|
+
├── .github/
|
|
751
|
+
│ └── workflows/
|
|
752
|
+
│ ├── ci.yml # Continuous integration workflow
|
|
753
|
+
│ ├── codeql.yml # CodeQL security analysis
|
|
754
|
+
│ └── publish.yml # NPM/CDN publish workflow
|
|
755
|
+
├── assets/
|
|
756
|
+
│ ├── logo.png # Project logo
|
|
757
|
+
│ └── preview.png # Editor preview screenshot
|
|
755
758
|
├── demo/
|
|
756
|
-
│
|
|
757
|
-
│ └── logo.png
|
|
759
|
+
│ ├── index.html # Interactive demo page
|
|
760
|
+
│ └── logo.png # Demo page logo
|
|
761
|
+
├── dist/
|
|
762
|
+
│ ├── neiki-editor.css # Editor styles (unminified)
|
|
763
|
+
│ ├── neiki-editor.js # Editor core (unminified)
|
|
764
|
+
│ ├── neiki-editor.min.css # Minified styles
|
|
765
|
+
│ └── neiki-editor.min.js # Minified editor + embedded CSS (recommended)
|
|
758
766
|
├── php/
|
|
759
|
-
│ └── neiki-editor.php
|
|
760
|
-
├──
|
|
761
|
-
├──
|
|
762
|
-
|
|
763
|
-
├──
|
|
764
|
-
├──
|
|
765
|
-
├──
|
|
766
|
-
├── CODE_OF_CONDUCT.md
|
|
767
|
-
|
|
767
|
+
│ └── neiki-editor.php # PHP integration helper
|
|
768
|
+
├── src/
|
|
769
|
+
│ ├── neiki-editor.css # Source CSS styles
|
|
770
|
+
│ └── neiki-editor.js # Source JavaScript
|
|
771
|
+
├── .gitattributes # Git attributes configuration
|
|
772
|
+
├── .gitignore # Git ignore rules
|
|
773
|
+
├── CHANGELOG.md # Project changelog
|
|
774
|
+
├── CODE_OF_CONDUCT.md # Community code of conduct
|
|
775
|
+
├── CONTRIBUTING.md # Contribution guidelines
|
|
776
|
+
├── LICENSE # AGPL-3.0 license
|
|
777
|
+
├── README.md # Project documentation
|
|
778
|
+
├── SECURITY.md # Security policy
|
|
779
|
+
├── package-lock.json # NPM lock file
|
|
780
|
+
└── package.json # NPM package configuration
|
|
768
781
|
```
|
|
769
782
|
|
|
770
783
|
---
|
package/dist/neiki-editor.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NeikiEditor - Production-Ready WYSIWYG Rich Text Editor
|
|
3
3
|
* CSS Stylesheet
|
|
4
|
-
* Version: 3.0.
|
|
4
|
+
* Version: 3.0.3
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/* ============================================
|
|
@@ -2123,6 +2123,12 @@
|
|
|
2123
2123
|
pointer-events: none;
|
|
2124
2124
|
}
|
|
2125
2125
|
|
|
2126
|
+
@media (hover: none), (pointer: coarse) {
|
|
2127
|
+
.neiki-block-grip {
|
|
2128
|
+
display: none !important;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2126
2132
|
.neiki-block-ghost {
|
|
2127
2133
|
position: fixed;
|
|
2128
2134
|
z-index: 100000;
|
package/dist/neiki-editor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NeikiEditor - A Modern WYSIWYG Editor
|
|
3
|
-
* Version: 3.0.
|
|
3
|
+
* Version: 3.0.3
|
|
4
4
|
*
|
|
5
5
|
* A lightweight, feature-rich text editor with support for:
|
|
6
6
|
* - Rich text formatting (bold, italic, underline, etc.)
|
|
@@ -196,6 +196,9 @@
|
|
|
196
196
|
'imageToolbar.dragToMove': 'Drag to move',
|
|
197
197
|
'videoToolbar.replaceVideo': 'Replace Video',
|
|
198
198
|
'videoToolbar.deleteVideo': 'Delete Video',
|
|
199
|
+
'blockToolbar.moveUp': 'Move block up',
|
|
200
|
+
'blockToolbar.moveDown': 'Move block down',
|
|
201
|
+
'blockToolbar.dragToReorder': 'Drag to reorder',
|
|
199
202
|
|
|
200
203
|
// Placeholder
|
|
201
204
|
'placeholder': 'Start typing...'
|
|
@@ -365,6 +368,9 @@
|
|
|
365
368
|
'imageToolbar.dragToMove': 'Přetáhněte pro přesun',
|
|
366
369
|
'videoToolbar.replaceVideo': 'Nahradit video',
|
|
367
370
|
'videoToolbar.deleteVideo': 'Smazat video',
|
|
371
|
+
'blockToolbar.moveUp': 'Přesunout blok nahoru',
|
|
372
|
+
'blockToolbar.moveDown': 'Přesunout blok dolů',
|
|
373
|
+
'blockToolbar.dragToReorder': 'Přetažením změnit pořadí',
|
|
368
374
|
|
|
369
375
|
'placeholder': 'Začněte psát...'
|
|
370
376
|
},
|
|
@@ -391,6 +397,7 @@
|
|
|
391
397
|
'toolbar.outdent': '减少缩进',
|
|
392
398
|
'toolbar.link': '插入链接 (Ctrl+K)',
|
|
393
399
|
'toolbar.image': '插入图片',
|
|
400
|
+
'toolbar.video': '插入视频',
|
|
394
401
|
'toolbar.table': '插入表格',
|
|
395
402
|
'toolbar.blockquote': '引用',
|
|
396
403
|
'toolbar.viewCode': '查看代码 (HTML)',
|
|
@@ -423,6 +430,7 @@
|
|
|
423
430
|
'font.cursive': '手写',
|
|
424
431
|
'insert.link': '链接',
|
|
425
432
|
'insert.image': '图片',
|
|
433
|
+
'insert.video': '视频',
|
|
426
434
|
'insert.table': '表格',
|
|
427
435
|
'insert.emoji': '表情',
|
|
428
436
|
'insert.symbol': '符号',
|
|
@@ -462,6 +470,15 @@
|
|
|
462
470
|
'modal.describeImage': '描述图片',
|
|
463
471
|
'modal.widthOptional': '宽度(可选)',
|
|
464
472
|
'modal.invalidImageFile': '请选择有效的图片文件。',
|
|
473
|
+
'modal.insertVideo': '插入视频',
|
|
474
|
+
'modal.uploadVideo': '上传视频',
|
|
475
|
+
'modal.convertedVideoToBase64': '将转换为base64',
|
|
476
|
+
'modal.videoUrl': '视频URL',
|
|
477
|
+
'modal.videoTitle': '视频标题',
|
|
478
|
+
'modal.describeVideo': '描述视频',
|
|
479
|
+
'modal.invalidVideoFile': '请选择有效的视频文件。',
|
|
480
|
+
'modal.uploadingVideo': '上传中...',
|
|
481
|
+
'modal.videoUploadError': '视频上传失败,请重试。',
|
|
465
482
|
'modal.insertTable': '插入表格',
|
|
466
483
|
'modal.rows': '行',
|
|
467
484
|
'modal.columns': '列',
|
|
@@ -498,6 +515,9 @@
|
|
|
498
515
|
'imageToolbar.dragToMove': '拖动移动',
|
|
499
516
|
'videoToolbar.replaceVideo': '替换视频',
|
|
500
517
|
'videoToolbar.deleteVideo': '删除视频',
|
|
518
|
+
'blockToolbar.moveUp': '向上移动块',
|
|
519
|
+
'blockToolbar.moveDown': '向下移动块',
|
|
520
|
+
'blockToolbar.dragToReorder': '拖动以重新排序',
|
|
501
521
|
|
|
502
522
|
'placeholder': '开始输入...'
|
|
503
523
|
},
|
|
@@ -523,6 +543,7 @@
|
|
|
523
543
|
'toolbar.outdent': 'Disminuir sangría',
|
|
524
544
|
'toolbar.link': 'Insertar enlace (Ctrl+K)',
|
|
525
545
|
'toolbar.image': 'Insertar imagen',
|
|
546
|
+
'toolbar.video': 'Insertar video',
|
|
526
547
|
'toolbar.table': 'Insertar tabla',
|
|
527
548
|
'toolbar.blockquote': 'Cita',
|
|
528
549
|
'toolbar.viewCode': 'Ver código (HTML)',
|
|
@@ -555,6 +576,7 @@
|
|
|
555
576
|
'font.cursive': 'Cursiva',
|
|
556
577
|
'insert.link': 'Enlace',
|
|
557
578
|
'insert.image': 'Imagen',
|
|
579
|
+
'insert.video': 'Video',
|
|
558
580
|
'insert.table': 'Tabla',
|
|
559
581
|
'insert.emoji': 'Emoji',
|
|
560
582
|
'insert.symbol': 'Símbolo',
|
|
@@ -594,6 +616,15 @@
|
|
|
594
616
|
'modal.describeImage': 'Describir la imagen',
|
|
595
617
|
'modal.widthOptional': 'Ancho (opcional)',
|
|
596
618
|
'modal.invalidImageFile': 'Por favor, seleccione un archivo de imagen válido.',
|
|
619
|
+
'modal.insertVideo': 'Insertar video',
|
|
620
|
+
'modal.uploadVideo': 'Subir video',
|
|
621
|
+
'modal.convertedVideoToBase64': 'Se convertirá a base64',
|
|
622
|
+
'modal.videoUrl': 'URL de video',
|
|
623
|
+
'modal.videoTitle': 'Título del video',
|
|
624
|
+
'modal.describeVideo': 'Describir el video',
|
|
625
|
+
'modal.invalidVideoFile': 'Por favor, seleccione un archivo de video válido.',
|
|
626
|
+
'modal.uploadingVideo': 'Subiendo...',
|
|
627
|
+
'modal.videoUploadError': 'Error al subir el video. Inténtelo de nuevo.',
|
|
597
628
|
'modal.insertTable': 'Insertar tabla',
|
|
598
629
|
'modal.rows': 'Filas',
|
|
599
630
|
'modal.columns': 'Columnas',
|
|
@@ -630,6 +661,9 @@
|
|
|
630
661
|
'imageToolbar.dragToMove': 'Arrastrar para mover',
|
|
631
662
|
'videoToolbar.replaceVideo': 'Reemplazar video',
|
|
632
663
|
'videoToolbar.deleteVideo': 'Eliminar video',
|
|
664
|
+
'blockToolbar.moveUp': 'Mover bloque arriba',
|
|
665
|
+
'blockToolbar.moveDown': 'Mover bloque abajo',
|
|
666
|
+
'blockToolbar.dragToReorder': 'Arrastrar para reordenar',
|
|
633
667
|
|
|
634
668
|
'placeholder': 'Empiece a escribir...'
|
|
635
669
|
},
|
|
@@ -655,6 +689,7 @@
|
|
|
655
689
|
'toolbar.outdent': 'Einzug verkleinern',
|
|
656
690
|
'toolbar.link': 'Link einfügen (Strg+K)',
|
|
657
691
|
'toolbar.image': 'Bild einfügen',
|
|
692
|
+
'toolbar.video': 'Video einfügen',
|
|
658
693
|
'toolbar.table': 'Tabelle einfügen',
|
|
659
694
|
'toolbar.blockquote': 'Zitat',
|
|
660
695
|
'toolbar.viewCode': 'Code anzeigen (HTML)',
|
|
@@ -687,6 +722,7 @@
|
|
|
687
722
|
'font.cursive': 'Schreibschrift',
|
|
688
723
|
'insert.link': 'Link',
|
|
689
724
|
'insert.image': 'Bild',
|
|
725
|
+
'insert.video': 'Video',
|
|
690
726
|
'insert.table': 'Tabelle',
|
|
691
727
|
'insert.emoji': 'Emoji',
|
|
692
728
|
'insert.symbol': 'Symbol',
|
|
@@ -726,6 +762,15 @@
|
|
|
726
762
|
'modal.describeImage': 'Bild beschreiben',
|
|
727
763
|
'modal.widthOptional': 'Breite (optional)',
|
|
728
764
|
'modal.invalidImageFile': 'Bitte wählen Sie eine gültige Bilddatei.',
|
|
765
|
+
'modal.insertVideo': 'Video einfügen',
|
|
766
|
+
'modal.uploadVideo': 'Video hochladen',
|
|
767
|
+
'modal.convertedVideoToBase64': 'Wird in Base64 konvertiert',
|
|
768
|
+
'modal.videoUrl': 'Video-URL',
|
|
769
|
+
'modal.videoTitle': 'Videotitel',
|
|
770
|
+
'modal.describeVideo': 'Video beschreiben',
|
|
771
|
+
'modal.invalidVideoFile': 'Bitte wählen Sie eine gültige Videodatei.',
|
|
772
|
+
'modal.uploadingVideo': 'Hochladen...',
|
|
773
|
+
'modal.videoUploadError': 'Video-Upload fehlgeschlagen. Bitte versuchen Sie es erneut.',
|
|
729
774
|
'modal.insertTable': 'Tabelle einfügen',
|
|
730
775
|
'modal.rows': 'Zeilen',
|
|
731
776
|
'modal.columns': 'Spalten',
|
|
@@ -762,6 +807,9 @@
|
|
|
762
807
|
'imageToolbar.dragToMove': 'Ziehen zum Verschieben',
|
|
763
808
|
'videoToolbar.replaceVideo': 'Video ersetzen',
|
|
764
809
|
'videoToolbar.deleteVideo': 'Video löschen',
|
|
810
|
+
'blockToolbar.moveUp': 'Block nach oben verschieben',
|
|
811
|
+
'blockToolbar.moveDown': 'Block nach unten verschieben',
|
|
812
|
+
'blockToolbar.dragToReorder': 'Zum Neuordnen ziehen',
|
|
765
813
|
|
|
766
814
|
'placeholder': 'Hier schreiben...'
|
|
767
815
|
},
|
|
@@ -787,6 +835,7 @@
|
|
|
787
835
|
'toolbar.outdent': 'Diminuer le retrait',
|
|
788
836
|
'toolbar.link': 'Insérer un lien (Ctrl+K)',
|
|
789
837
|
'toolbar.image': 'Insérer une image',
|
|
838
|
+
'toolbar.video': 'Insérer une vidéo',
|
|
790
839
|
'toolbar.table': 'Insérer un tableau',
|
|
791
840
|
'toolbar.blockquote': 'Citation',
|
|
792
841
|
'toolbar.viewCode': 'Voir le code (HTML)',
|
|
@@ -819,6 +868,7 @@
|
|
|
819
868
|
'font.cursive': 'Cursive',
|
|
820
869
|
'insert.link': 'Lien',
|
|
821
870
|
'insert.image': 'Image',
|
|
871
|
+
'insert.video': 'Vidéo',
|
|
822
872
|
'insert.table': 'Tableau',
|
|
823
873
|
'insert.emoji': 'Emoji',
|
|
824
874
|
'insert.symbol': 'Symbole',
|
|
@@ -858,6 +908,15 @@
|
|
|
858
908
|
'modal.describeImage': 'Décrire l\'image',
|
|
859
909
|
'modal.widthOptional': 'Largeur (optionnel)',
|
|
860
910
|
'modal.invalidImageFile': 'Veuillez sélectionner un fichier image valide.',
|
|
911
|
+
'modal.insertVideo': 'Insérer une vidéo',
|
|
912
|
+
'modal.uploadVideo': 'Téléverser une vidéo',
|
|
913
|
+
'modal.convertedVideoToBase64': 'Sera converti en base64',
|
|
914
|
+
'modal.videoUrl': 'URL de la vidéo',
|
|
915
|
+
'modal.videoTitle': 'Titre de la vidéo',
|
|
916
|
+
'modal.describeVideo': 'Décrire la vidéo',
|
|
917
|
+
'modal.invalidVideoFile': 'Veuillez sélectionner un fichier vidéo valide.',
|
|
918
|
+
'modal.uploadingVideo': 'Téléversement...',
|
|
919
|
+
'modal.videoUploadError': 'Échec du téléversement de la vidéo. Veuillez réessayer.',
|
|
861
920
|
'modal.insertTable': 'Insérer un tableau',
|
|
862
921
|
'modal.rows': 'Lignes',
|
|
863
922
|
'modal.columns': 'Colonnes',
|
|
@@ -894,6 +953,9 @@
|
|
|
894
953
|
'imageToolbar.dragToMove': 'Glisser pour déplacer',
|
|
895
954
|
'videoToolbar.replaceVideo': 'Remplacer la vidéo',
|
|
896
955
|
'videoToolbar.deleteVideo': 'Supprimer la vidéo',
|
|
956
|
+
'blockToolbar.moveUp': 'Déplacer le bloc vers le haut',
|
|
957
|
+
'blockToolbar.moveDown': 'Déplacer le bloc vers le bas',
|
|
958
|
+
'blockToolbar.dragToReorder': 'Glisser pour réorganiser',
|
|
897
959
|
|
|
898
960
|
'placeholder': 'Commencez à écrire...'
|
|
899
961
|
},
|
|
@@ -919,6 +981,7 @@
|
|
|
919
981
|
'toolbar.outdent': 'Diminuir recuo',
|
|
920
982
|
'toolbar.link': 'Inserir link (Ctrl+K)',
|
|
921
983
|
'toolbar.image': 'Inserir imagem',
|
|
984
|
+
'toolbar.video': 'Inserir vídeo',
|
|
922
985
|
'toolbar.table': 'Inserir tabela',
|
|
923
986
|
'toolbar.blockquote': 'Citação',
|
|
924
987
|
'toolbar.viewCode': 'Ver código (HTML)',
|
|
@@ -951,6 +1014,7 @@
|
|
|
951
1014
|
'font.cursive': 'Cursiva',
|
|
952
1015
|
'insert.link': 'Link',
|
|
953
1016
|
'insert.image': 'Imagem',
|
|
1017
|
+
'insert.video': 'Vídeo',
|
|
954
1018
|
'insert.table': 'Tabela',
|
|
955
1019
|
'insert.emoji': 'Emoji',
|
|
956
1020
|
'insert.symbol': 'Símbolo',
|
|
@@ -990,6 +1054,15 @@
|
|
|
990
1054
|
'modal.describeImage': 'Descrever a imagem',
|
|
991
1055
|
'modal.widthOptional': 'Largura (opcional)',
|
|
992
1056
|
'modal.invalidImageFile': 'Por favor, selecione um arquivo de imagem válido.',
|
|
1057
|
+
'modal.insertVideo': 'Inserir vídeo',
|
|
1058
|
+
'modal.uploadVideo': 'Enviar vídeo',
|
|
1059
|
+
'modal.convertedVideoToBase64': 'Será convertido para base64',
|
|
1060
|
+
'modal.videoUrl': 'URL do vídeo',
|
|
1061
|
+
'modal.videoTitle': 'Título do vídeo',
|
|
1062
|
+
'modal.describeVideo': 'Descrever o vídeo',
|
|
1063
|
+
'modal.invalidVideoFile': 'Por favor, selecione um arquivo de vídeo válido.',
|
|
1064
|
+
'modal.uploadingVideo': 'Enviando...',
|
|
1065
|
+
'modal.videoUploadError': 'Falha no envio do vídeo. Tente novamente.',
|
|
993
1066
|
'modal.insertTable': 'Inserir tabela',
|
|
994
1067
|
'modal.rows': 'Linhas',
|
|
995
1068
|
'modal.columns': 'Colunas',
|
|
@@ -1026,6 +1099,9 @@
|
|
|
1026
1099
|
'imageToolbar.dragToMove': 'Arraste para mover',
|
|
1027
1100
|
'videoToolbar.replaceVideo': 'Substituir vídeo',
|
|
1028
1101
|
'videoToolbar.deleteVideo': 'Excluir vídeo',
|
|
1102
|
+
'blockToolbar.moveUp': 'Mover bloco para cima',
|
|
1103
|
+
'blockToolbar.moveDown': 'Mover bloco para baixo',
|
|
1104
|
+
'blockToolbar.dragToReorder': 'Arraste para reordenar',
|
|
1029
1105
|
|
|
1030
1106
|
'placeholder': 'Comece a digitar...'
|
|
1031
1107
|
},
|
|
@@ -1051,6 +1127,7 @@
|
|
|
1051
1127
|
'toolbar.outdent': 'インデント減',
|
|
1052
1128
|
'toolbar.link': 'リンク挿入 (Ctrl+K)',
|
|
1053
1129
|
'toolbar.image': '画像挿入',
|
|
1130
|
+
'toolbar.video': '動画挿入',
|
|
1054
1131
|
'toolbar.table': '表挿入',
|
|
1055
1132
|
'toolbar.blockquote': '引用',
|
|
1056
1133
|
'toolbar.viewCode': 'コード表示 (HTML)',
|
|
@@ -1083,6 +1160,7 @@
|
|
|
1083
1160
|
'font.cursive': '手書き',
|
|
1084
1161
|
'insert.link': 'リンク',
|
|
1085
1162
|
'insert.image': '画像',
|
|
1163
|
+
'insert.video': '動画',
|
|
1086
1164
|
'insert.table': '表',
|
|
1087
1165
|
'insert.emoji': '絵文字',
|
|
1088
1166
|
'insert.symbol': '記号',
|
|
@@ -1122,6 +1200,15 @@
|
|
|
1122
1200
|
'modal.describeImage': '画像の説明',
|
|
1123
1201
|
'modal.widthOptional': '幅(任意)',
|
|
1124
1202
|
'modal.invalidImageFile': '有効な画像ファイルを選択してください。',
|
|
1203
|
+
'modal.insertVideo': '動画挿入',
|
|
1204
|
+
'modal.uploadVideo': '動画アップロード',
|
|
1205
|
+
'modal.convertedVideoToBase64': 'Base64に変換されます',
|
|
1206
|
+
'modal.videoUrl': '動画URL',
|
|
1207
|
+
'modal.videoTitle': '動画タイトル',
|
|
1208
|
+
'modal.describeVideo': '動画の説明',
|
|
1209
|
+
'modal.invalidVideoFile': '有効な動画ファイルを選択してください。',
|
|
1210
|
+
'modal.uploadingVideo': 'アップロード中...',
|
|
1211
|
+
'modal.videoUploadError': '動画のアップロードに失敗しました。もう一度お試しください。',
|
|
1125
1212
|
'modal.insertTable': '表挿入',
|
|
1126
1213
|
'modal.rows': '行',
|
|
1127
1214
|
'modal.columns': '列',
|
|
@@ -1158,6 +1245,9 @@
|
|
|
1158
1245
|
'imageToolbar.dragToMove': 'ドラッグで移動',
|
|
1159
1246
|
'videoToolbar.replaceVideo': '動画を置換',
|
|
1160
1247
|
'videoToolbar.deleteVideo': '動画を削除',
|
|
1248
|
+
'blockToolbar.moveUp': 'ブロックを上へ移動',
|
|
1249
|
+
'blockToolbar.moveDown': 'ブロックを下へ移動',
|
|
1250
|
+
'blockToolbar.dragToReorder': 'ドラッグして並べ替え',
|
|
1161
1251
|
|
|
1162
1252
|
'placeholder': '入力してください...'
|
|
1163
1253
|
}
|
|
@@ -2798,10 +2888,10 @@
|
|
|
2798
2888
|
<button class="neiki-modal-close" type="button">${Icons.close}</button>
|
|
2799
2889
|
</div>
|
|
2800
2890
|
<div class="neiki-modal-body" style="text-align: center; padding: 24px 20px;">
|
|
2801
|
-
<img src="https://github.com/neikiri/neiki-editor/raw/main/logo.png" alt="Neiki's Editor" style="width:
|
|
2891
|
+
<img src="https://github.com/neikiri/neiki-editor/raw/main/assets/logo.png" alt="Neiki's Editor" style="width: 240px; height: auto; margin: 0 auto 16px; display: block;">
|
|
2802
2892
|
<div style="font-size: 14px; line-height: 2; color: var(--neiki-text-primary);">
|
|
2803
2893
|
<div><strong>${Utils.escapeHTML(t('help.author'))}:</strong> neikiri (Jindřich Stoklasa)</div>
|
|
2804
|
-
<div><strong>${Utils.escapeHTML(t('help.version'))}:</strong> 3.0.
|
|
2894
|
+
<div><strong>${Utils.escapeHTML(t('help.version'))}:</strong> 3.0.3</div>
|
|
2805
2895
|
<div><strong>${Utils.escapeHTML(t('help.github'))}:</strong> <a href="https://github.com/neikiri/neiki-editor" target="_blank" rel="noopener noreferrer" style="color: var(--neiki-accent);">github.com/neikiri/neiki-editor</a></div>
|
|
2806
2896
|
<div><strong>${Utils.escapeHTML(t('help.documentation'))}:</strong> <a href="https://github.com/neikiri/neiki-editor/wiki" target="_blank" rel="noopener noreferrer" style="color: var(--neiki-accent);">Wiki</a></div>
|
|
2807
2897
|
</div>
|
|
@@ -3382,15 +3472,18 @@
|
|
|
3382
3472
|
insertHorizontalRule() { this.exec('insertHorizontalRule'); }
|
|
3383
3473
|
|
|
3384
3474
|
formatBlock(tag) {
|
|
3385
|
-
// Toggle blockquote: if already inside one, revert to paragraph
|
|
3386
3475
|
if (tag === 'blockquote') {
|
|
3387
3476
|
const sel = window.getSelection();
|
|
3388
3477
|
if (sel && sel.rangeCount) {
|
|
3389
|
-
|
|
3478
|
+
const range = sel.getRangeAt(0);
|
|
3479
|
+
let node = range.startContainer;
|
|
3390
3480
|
if (node.nodeType === Node.TEXT_NODE) node = node.parentNode;
|
|
3391
3481
|
const bq = node.closest ? node.closest('blockquote') : null;
|
|
3392
3482
|
if (bq && this.editor.contentArea.contains(bq)) {
|
|
3393
|
-
this.
|
|
3483
|
+
this._unwrapBlockquote(bq, range);
|
|
3484
|
+
this.editor.history.record();
|
|
3485
|
+
this.editor.updateToolbar();
|
|
3486
|
+
this.editor.triggerChange();
|
|
3394
3487
|
return;
|
|
3395
3488
|
}
|
|
3396
3489
|
}
|
|
@@ -3398,6 +3491,65 @@
|
|
|
3398
3491
|
this.exec('formatBlock', `<${tag}>`);
|
|
3399
3492
|
}
|
|
3400
3493
|
|
|
3494
|
+
_unwrapBlockquote(blockquote, range) {
|
|
3495
|
+
const parent = blockquote.parentNode;
|
|
3496
|
+
const marker = document.createElement('span');
|
|
3497
|
+
marker.setAttribute('data-neiki-selection-marker', 'true');
|
|
3498
|
+
marker.style.display = 'none';
|
|
3499
|
+
|
|
3500
|
+
if (range && range.collapsed) {
|
|
3501
|
+
const markerRange = range.cloneRange();
|
|
3502
|
+
markerRange.insertNode(marker);
|
|
3503
|
+
}
|
|
3504
|
+
|
|
3505
|
+
let inlineParagraph = null;
|
|
3506
|
+
const insertedNodes = [];
|
|
3507
|
+
const flushInlineParagraph = () => {
|
|
3508
|
+
if (inlineParagraph) {
|
|
3509
|
+
parent.insertBefore(inlineParagraph, blockquote);
|
|
3510
|
+
insertedNodes.push(inlineParagraph);
|
|
3511
|
+
inlineParagraph = null;
|
|
3512
|
+
}
|
|
3513
|
+
};
|
|
3514
|
+
|
|
3515
|
+
while (blockquote.firstChild) {
|
|
3516
|
+
const child = blockquote.firstChild;
|
|
3517
|
+
if (this._isTopLevelBlock(child)) {
|
|
3518
|
+
flushInlineParagraph();
|
|
3519
|
+
parent.insertBefore(child, blockquote);
|
|
3520
|
+
insertedNodes.push(child);
|
|
3521
|
+
} else {
|
|
3522
|
+
if (!inlineParagraph) inlineParagraph = document.createElement('p');
|
|
3523
|
+
inlineParagraph.appendChild(child);
|
|
3524
|
+
}
|
|
3525
|
+
}
|
|
3526
|
+
|
|
3527
|
+
flushInlineParagraph();
|
|
3528
|
+
parent.removeChild(blockquote);
|
|
3529
|
+
|
|
3530
|
+
const sel = window.getSelection();
|
|
3531
|
+
const restoredMarker = parent.querySelector('[data-neiki-selection-marker="true"]');
|
|
3532
|
+
if (sel && restoredMarker) {
|
|
3533
|
+
const restoredRange = document.createRange();
|
|
3534
|
+
restoredRange.setStartBefore(restoredMarker);
|
|
3535
|
+
restoredRange.collapse(true);
|
|
3536
|
+
restoredMarker.remove();
|
|
3537
|
+
sel.removeAllRanges();
|
|
3538
|
+
sel.addRange(restoredRange);
|
|
3539
|
+
} else if (sel && insertedNodes.length > 0) {
|
|
3540
|
+
const fallbackRange = document.createRange();
|
|
3541
|
+
fallbackRange.setStart(insertedNodes[0], 0);
|
|
3542
|
+
fallbackRange.collapse(true);
|
|
3543
|
+
sel.removeAllRanges();
|
|
3544
|
+
sel.addRange(fallbackRange);
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
|
|
3548
|
+
_isTopLevelBlock(node) {
|
|
3549
|
+
if (!node || node.nodeType !== Node.ELEMENT_NODE) return false;
|
|
3550
|
+
return ['ADDRESS', 'ARTICLE', 'ASIDE', 'BLOCKQUOTE', 'DIV', 'DL', 'FIGURE', 'FOOTER', 'FORM', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEADER', 'HR', 'MAIN', 'OL', 'P', 'PRE', 'SECTION', 'TABLE', 'UL'].includes(node.tagName);
|
|
3551
|
+
}
|
|
3552
|
+
|
|
3401
3553
|
fontSize(sizeStr) {
|
|
3402
3554
|
this.editor.focus();
|
|
3403
3555
|
this._expandToWordIfCollapsed();
|
|
@@ -4972,7 +5124,14 @@
|
|
|
4972
5124
|
// Remove grip handles, placeholders, resize handles
|
|
4973
5125
|
clone.querySelectorAll('.neiki-block-grip, .neiki-block-placeholder, .neiki-table-col-resize-handle, .neiki-img-resize-handle, .neiki-img-size-label, .neiki-img-toolbar').forEach(el => el.remove());
|
|
4974
5126
|
this.removeStrayGripSvgs(clone);
|
|
4975
|
-
|
|
5127
|
+
const html = clone.innerHTML;
|
|
5128
|
+
// Return empty string when the editor contains only the default empty
|
|
5129
|
+
// block that browsers insert automatically (e.g. <p><br></p>).
|
|
5130
|
+
// This prevents a blank-looking editor from submitting a non-empty value.
|
|
5131
|
+
if (/^(\s|<p>(\s| |<br\s*\/?>)*<\/p>|<br\s*\/?>)*$/i.test(html)) {
|
|
5132
|
+
return '';
|
|
5133
|
+
}
|
|
5134
|
+
return html;
|
|
4976
5135
|
}
|
|
4977
5136
|
|
|
4978
5137
|
removeStrayGripSvgs(root = this.contentArea) {
|
|
@@ -5958,6 +6117,8 @@
|
|
|
5958
6117
|
const moveUpBtn = document.createElement('button');
|
|
5959
6118
|
moveUpBtn.className = 'neiki-img-toolbar-btn';
|
|
5960
6119
|
moveUpBtn.type = 'button';
|
|
6120
|
+
moveUpBtn.title = t('blockToolbar.moveUp');
|
|
6121
|
+
moveUpBtn.setAttribute('aria-label', t('blockToolbar.moveUp'));
|
|
5961
6122
|
moveUpBtn.innerHTML = Icons.moveUp;
|
|
5962
6123
|
moveUpBtn.addEventListener('click', (e) => {
|
|
5963
6124
|
e.preventDefault();
|
|
@@ -5972,6 +6133,8 @@
|
|
|
5972
6133
|
const moveDownBtn = document.createElement('button');
|
|
5973
6134
|
moveDownBtn.className = 'neiki-img-toolbar-btn';
|
|
5974
6135
|
moveDownBtn.type = 'button';
|
|
6136
|
+
moveDownBtn.title = t('blockToolbar.moveDown');
|
|
6137
|
+
moveDownBtn.setAttribute('aria-label', t('blockToolbar.moveDown'));
|
|
5975
6138
|
moveDownBtn.innerHTML = Icons.moveDown;
|
|
5976
6139
|
moveDownBtn.addEventListener('click', (e) => {
|
|
5977
6140
|
e.preventDefault();
|
|
@@ -6589,7 +6752,7 @@
|
|
|
6589
6752
|
const grip = document.createElement('div');
|
|
6590
6753
|
grip.className = 'neiki-block-grip';
|
|
6591
6754
|
grip.innerHTML = Icons.grip;
|
|
6592
|
-
grip.title = '
|
|
6755
|
+
grip.title = t('blockToolbar.dragToReorder');
|
|
6593
6756
|
grip.contentEditable = 'false';
|
|
6594
6757
|
grip._block = block;
|
|
6595
6758
|
|
|
@@ -6745,8 +6908,8 @@
|
|
|
6745
6908
|
|
|
6746
6909
|
// Move block buttons (left side)
|
|
6747
6910
|
const moveButtons = [
|
|
6748
|
-
{ item: 'moveUp', icon: Icons.moveUp, title: '
|
|
6749
|
-
{ item: 'moveDown', icon: Icons.moveDown, title: '
|
|
6911
|
+
{ item: 'moveUp', icon: Icons.moveUp, title: t('blockToolbar.moveUp') },
|
|
6912
|
+
{ item: 'moveDown', icon: Icons.moveDown, title: t('blockToolbar.moveDown') }
|
|
6750
6913
|
];
|
|
6751
6914
|
|
|
6752
6915
|
moveButtons.forEach(({ item, icon, title }) => {
|