@flogeez/angular-tiptap-editor 0.3.2 → 0.3.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.
@@ -3510,7 +3510,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
3510
3510
  `, styles: [".tiptap-toolbar{display:flex;align-items:center;gap:4px;padding:4px 8px;background:#f8f9fa;border-bottom:1px solid #e2e8f0;flex-wrap:wrap;min-height:32px;position:relative}.toolbar-group{display:flex;align-items:center;gap:2px;padding:0 4px}.toolbar-separator{width:1px;height:24px;background:#e2e8f0;margin:0 4px}@media (max-width: 768px){.tiptap-toolbar{padding:6px 8px;gap:2px}.toolbar-group{gap:1px}}@keyframes toolbarSlideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.tiptap-toolbar{animation:toolbarSlideIn .3s cubic-bezier(.4,0,.2,1)}\n"] }]
3511
3511
  }], ctorParameters: () => [{ type: EditorCommandsService }] });
3512
3512
 
3513
- const DEFAULT_SLASH_COMMANDS = [
3513
+ const DEFAULT_SLASH_COMMANDS$1 = [
3514
3514
  {
3515
3515
  title: "Titre 1",
3516
3516
  description: "Grand titre de section",
@@ -3647,7 +3647,7 @@ class TiptapSlashCommandsComponent {
3647
3647
  constructor() {
3648
3648
  this.editor = input.required();
3649
3649
  this.config = input({
3650
- commands: DEFAULT_SLASH_COMMANDS,
3650
+ commands: DEFAULT_SLASH_COMMANDS$1,
3651
3651
  });
3652
3652
  // Output pour l'upload d'image
3653
3653
  this.imageUploadRequested = output();
@@ -3660,7 +3660,7 @@ class TiptapSlashCommandsComponent {
3660
3660
  // Signal pour l'index sélectionné
3661
3661
  this.selectedIndex = signal(0);
3662
3662
  this.commands = computed(() => {
3663
- const configCommands = this.config().commands || DEFAULT_SLASH_COMMANDS;
3663
+ const configCommands = this.config().commands || DEFAULT_SLASH_COMMANDS$1;
3664
3664
  // Remplacer la commande image par une version qui utilise l'output
3665
3665
  return configCommands.map((command) => {
3666
3666
  if (command.icon === "image") {
@@ -4380,6 +4380,178 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
4380
4380
  }]
4381
4381
  }] });
4382
4382
 
4383
+ /**
4384
+ * Clés des commandes dans l'ordre de création
4385
+ */
4386
+ const SLASH_COMMAND_KEYS = [
4387
+ "heading1",
4388
+ "heading2",
4389
+ "heading3",
4390
+ "bulletList",
4391
+ "orderedList",
4392
+ "blockquote",
4393
+ "code",
4394
+ "image",
4395
+ "horizontalRule",
4396
+ "table",
4397
+ ];
4398
+ /**
4399
+ * Factory function pour créer les slash commands traduits
4400
+ */
4401
+ function createI18nSlashCommands(i18nService) {
4402
+ const slashCommands = i18nService.slashCommands();
4403
+ return [
4404
+ {
4405
+ title: slashCommands.heading1.title,
4406
+ description: slashCommands.heading1.description,
4407
+ icon: "format_h1",
4408
+ keywords: slashCommands.heading1.keywords,
4409
+ command: (editor) => editor.chain().focus().toggleHeading({ level: 1 }).run(),
4410
+ },
4411
+ {
4412
+ title: slashCommands.heading2.title,
4413
+ description: slashCommands.heading2.description,
4414
+ icon: "format_h2",
4415
+ keywords: slashCommands.heading2.keywords,
4416
+ command: (editor) => editor.chain().focus().toggleHeading({ level: 2 }).run(),
4417
+ },
4418
+ {
4419
+ title: slashCommands.heading3.title,
4420
+ description: slashCommands.heading3.description,
4421
+ icon: "format_h3",
4422
+ keywords: slashCommands.heading3.keywords,
4423
+ command: (editor) => editor.chain().focus().toggleHeading({ level: 3 }).run(),
4424
+ },
4425
+ {
4426
+ title: slashCommands.bulletList.title,
4427
+ description: slashCommands.bulletList.description,
4428
+ icon: "format_list_bulleted",
4429
+ keywords: slashCommands.bulletList.keywords,
4430
+ command: (editor) => editor.chain().focus().toggleBulletList().run(),
4431
+ },
4432
+ {
4433
+ title: slashCommands.orderedList.title,
4434
+ description: slashCommands.orderedList.description,
4435
+ icon: "format_list_numbered",
4436
+ keywords: slashCommands.orderedList.keywords,
4437
+ command: (editor) => editor.chain().focus().toggleOrderedList().run(),
4438
+ },
4439
+ {
4440
+ title: slashCommands.blockquote.title,
4441
+ description: slashCommands.blockquote.description,
4442
+ icon: "format_quote",
4443
+ keywords: slashCommands.blockquote.keywords,
4444
+ command: (editor) => editor.chain().focus().toggleBlockquote().run(),
4445
+ },
4446
+ {
4447
+ title: slashCommands.code.title,
4448
+ description: slashCommands.code.description,
4449
+ icon: "code",
4450
+ keywords: slashCommands.code.keywords,
4451
+ command: (editor) => editor.chain().focus().toggleCodeBlock().run(),
4452
+ },
4453
+ {
4454
+ title: slashCommands.image.title,
4455
+ description: slashCommands.image.description,
4456
+ icon: "image",
4457
+ keywords: slashCommands.image.keywords,
4458
+ command: (editor) => {
4459
+ // Créer un input file temporaire pour sélectionner une image
4460
+ const input = document.createElement("input");
4461
+ input.type = "file";
4462
+ input.accept = "image/*";
4463
+ input.style.display = "none";
4464
+ input.addEventListener("change", async (e) => {
4465
+ const file = e.target.files?.[0];
4466
+ if (file && file.type.startsWith("image/")) {
4467
+ try {
4468
+ // Utiliser la méthode de compression unifiée
4469
+ const canvas = document.createElement("canvas");
4470
+ const ctx = canvas.getContext("2d");
4471
+ const img = new Image();
4472
+ img.onload = () => {
4473
+ // Vérifier les dimensions (max 1920x1080)
4474
+ const maxWidth = 1920;
4475
+ const maxHeight = 1080;
4476
+ let { width, height } = img;
4477
+ // Redimensionner si nécessaire
4478
+ if (width > maxWidth || height > maxHeight) {
4479
+ const ratio = Math.min(maxWidth / width, maxHeight / height);
4480
+ width *= ratio;
4481
+ height *= ratio;
4482
+ }
4483
+ canvas.width = width;
4484
+ canvas.height = height;
4485
+ // Dessiner l'image redimensionnée
4486
+ ctx?.drawImage(img, 0, 0, width, height);
4487
+ // Convertir en base64 avec compression
4488
+ canvas.toBlob((blob) => {
4489
+ if (blob) {
4490
+ const reader = new FileReader();
4491
+ reader.onload = (e) => {
4492
+ const base64 = e.target?.result;
4493
+ if (base64) {
4494
+ // Utiliser setResizableImage avec toutes les propriétés
4495
+ editor
4496
+ .chain()
4497
+ .focus()
4498
+ .setResizableImage({
4499
+ src: base64,
4500
+ alt: file.name,
4501
+ title: `${file.name} (${Math.round(width)}×${Math.round(height)})`,
4502
+ width: Math.round(width),
4503
+ height: Math.round(height),
4504
+ })
4505
+ .run();
4506
+ }
4507
+ };
4508
+ reader.readAsDataURL(blob);
4509
+ }
4510
+ }, file.type, 0.8 // qualité de compression
4511
+ );
4512
+ };
4513
+ img.onerror = () => {
4514
+ console.error(i18nService.editor().imageLoadError);
4515
+ };
4516
+ img.src = URL.createObjectURL(file);
4517
+ }
4518
+ catch (error) {
4519
+ console.error("Error uploading image:", error);
4520
+ }
4521
+ }
4522
+ document.body.removeChild(input);
4523
+ });
4524
+ document.body.appendChild(input);
4525
+ input.click();
4526
+ },
4527
+ },
4528
+ {
4529
+ title: slashCommands.horizontalRule.title,
4530
+ description: slashCommands.horizontalRule.description,
4531
+ icon: "horizontal_rule",
4532
+ keywords: slashCommands.horizontalRule.keywords,
4533
+ command: (editor) => editor.chain().focus().setHorizontalRule().run(),
4534
+ },
4535
+ {
4536
+ title: slashCommands.table.title,
4537
+ description: slashCommands.table.description,
4538
+ icon: "table_view",
4539
+ keywords: slashCommands.table.keywords,
4540
+ command: (editor) => editor.chain().focus().insertTable({ rows: 3, cols: 3 }).run(),
4541
+ },
4542
+ ];
4543
+ }
4544
+ /**
4545
+ * Fonction utilitaire pour filtrer les slash commands selon les commandes actives
4546
+ */
4547
+ function filterSlashCommands(activeCommands, i18nService) {
4548
+ const allCommands = createI18nSlashCommands(i18nService);
4549
+ return allCommands.filter((command, index) => {
4550
+ const commandKey = SLASH_COMMAND_KEYS[index];
4551
+ return commandKey && activeCommands.has(commandKey);
4552
+ });
4553
+ }
4554
+
4383
4555
  // Configuration par défaut de la toolbar
4384
4556
  const DEFAULT_TOOLBAR_CONFIG = {
4385
4557
  bold: true,
@@ -4449,6 +4621,9 @@ const DEFAULT_CELL_MENU_CONFIG = {
4449
4621
  mergeCells: true,
4450
4622
  splitCell: true,
4451
4623
  };
4624
+ const DEFAULT_SLASH_COMMANDS = {
4625
+ commands: [], // Sera rempli par filterSlashCommands
4626
+ };
4452
4627
  class AngularTiptapEditorComponent {
4453
4628
  constructor() {
4454
4629
  // Nouveaux inputs avec signal
@@ -4539,7 +4714,15 @@ class AngularTiptapEditorComponent {
4539
4714
  ...this.imageUpload(),
4540
4715
  }));
4541
4716
  // Computed pour la configuration des slash commands
4542
- this.slashCommandsConfigComputed = computed(() => this.slashCommandsConfig() ?? { commands: undefined });
4717
+ this.slashCommandsConfigComputed = computed(() => {
4718
+ const config = this.slashCommandsConfig();
4719
+ if (config) {
4720
+ return config;
4721
+ }
4722
+ // Configuration par défaut avec toutes les commandes
4723
+ const allCommands = filterSlashCommands(new Set(SLASH_COMMAND_KEYS), this.i18nService);
4724
+ return { commands: allCommands };
4725
+ });
4543
4726
  this._destroyRef = inject(DestroyRef);
4544
4727
  // NgControl pour gérer les FormControls
4545
4728
  this.ngControl = inject(NgControl, { self: true, optional: true });
@@ -5031,181 +5214,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImpor
5031
5214
  `, styles: [".tiptap-editor{border:2px solid #e2e8f0;border-radius:8px;background:#fff;overflow:hidden;transition:border-color .2s ease}.tiptap-editor:focus-within{border-color:#3182ce}.tiptap-content{padding:16px;min-height:var(--editor-min-height, 200px);height:var(--editor-height, auto);max-height:var(--editor-max-height, none);overflow-y:var(--editor-overflow, visible);outline:none;position:relative}.tiptap-content.drag-over{background:#f0f8ff;border:2px dashed #3182ce}.character-count{padding:8px 16px;font-size:12px;color:#718096;text-align:right;border-top:1px solid #e2e8f0;background:#f8f9fa}.image-upload-container{position:relative;display:inline-block}:host ::ng-deep .ProseMirror{outline:none;line-height:1.6;color:#2d3748;min-height:100%;height:100%;word-wrap:break-word;overflow-wrap:break-word}:host ::ng-deep .ProseMirror h1{font-size:2em;font-weight:700;margin-top:0;margin-bottom:.5em}:host ::ng-deep .ProseMirror h2{font-size:1.5em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror h3{font-size:1.25em;font-weight:700;margin-top:1em;margin-bottom:.5em}:host ::ng-deep .ProseMirror p{margin:.5em 0}:host ::ng-deep .ProseMirror ul,:host ::ng-deep .ProseMirror ol{padding-left:2em;margin:.5em 0}:host ::ng-deep .ProseMirror blockquote{border-left:4px solid #e2e8f0;margin:1em 0;font-style:italic;background:#f8f9fa;padding:.5em 1em;border-radius:0 4px 4px 0}:host ::ng-deep .ProseMirror code{background:#f1f5f9;padding:.2em .4em;border-radius:3px;font-family:Monaco,Consolas,monospace;font-size:.9em}:host ::ng-deep .ProseMirror pre{background:#1a202c;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;margin:1em 0}:host ::ng-deep .ProseMirror pre code{background:none;color:inherit;padding:0}:host ::ng-deep .ProseMirror p.is-editor-empty:first-child:before{content:attr(data-placeholder);color:#a0aec0;pointer-events:none;float:left;height:0}:host ::ng-deep .ProseMirror[contenteditable=false]{pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img{cursor:default;pointer-events:none}:host ::ng-deep .ProseMirror[contenteditable=false] img:hover{transform:none;box-shadow:0 2px 8px #0000001a}:host ::ng-deep .ProseMirror[contenteditable=false] img.ProseMirror-selectednode{outline:none}:host ::ng-deep .ProseMirror img{position:relative;display:inline-block;max-width:100%;height:auto;cursor:pointer;transition:all .2s ease;border:2px solid transparent;border-radius:8px}:host ::ng-deep .ProseMirror img:hover{border-color:#e2e8f0;box-shadow:0 2px 4px #0000001a}:host ::ng-deep .ProseMirror img.ProseMirror-selectednode{border-color:#3182ce;box-shadow:0 0 0 3px #3182ce1a;transition:all .2s ease}:host ::ng-deep .ProseMirror .tiptap-image{max-width:100%;height:auto;border-radius:16px;box-shadow:0 4px 20px #00000014;margin:.5em 0;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);display:block;filter:brightness(1) contrast(1)}:host ::ng-deep .ProseMirror .tiptap-image:hover{box-shadow:0 8px 30px #0000001f;filter:brightness(1.02) contrast(1.02)}:host ::ng-deep .ProseMirror .tiptap-image.ProseMirror-selectednode{outline:2px solid #6366f1;outline-offset:2px;border-radius:16px;box-shadow:0 0 0 4px #6366f11a}:host ::ng-deep .image-container{margin:.5em 0;text-align:center;border-radius:16px;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1)}:host ::ng-deep .image-container.image-align-left{text-align:left}:host ::ng-deep .image-container.image-align-center{text-align:center}:host ::ng-deep .image-container.image-align-right{text-align:right}:host ::ng-deep .image-container img{display:inline-block;max-width:100%;height:auto;border-radius:16px}:host ::ng-deep .resizable-image-container{position:relative;display:inline-block;margin:.5em 0}:host ::ng-deep .resize-controls{position:absolute;inset:0;pointer-events:none;z-index:1000}:host ::ng-deep .resize-handle{position:absolute;width:12px;height:12px;background:#3b82f6;border:2px solid white;border-radius:50%;pointer-events:all;cursor:pointer;z-index:1001;transition:all .15s ease;box-shadow:0 2px 6px #0003}:host ::ng-deep .resize-handle:hover{background:#2563eb;box-shadow:0 3px 8px #0000004d}:host ::ng-deep .resize-handle:active{background:#1d4ed8}:host ::ng-deep .resize-handle-n:hover,:host ::ng-deep .resize-handle-s:hover{transform:translate(-50%) scale(1.2)}:host ::ng-deep .resize-handle-w:hover,:host ::ng-deep .resize-handle-e:hover{transform:translateY(-50%) scale(1.2)}:host ::ng-deep .resize-handle-n:active,:host ::ng-deep .resize-handle-s:active{transform:translate(-50%) scale(.9)}:host ::ng-deep .resize-handle-w:active,:host ::ng-deep .resize-handle-e:active{transform:translateY(-50%) scale(.9)}:host ::ng-deep .resize-handle-nw:hover,:host ::ng-deep .resize-handle-ne:hover,:host ::ng-deep .resize-handle-sw:hover,:host ::ng-deep .resize-handle-se:hover{transform:scale(1.2)}:host ::ng-deep .resize-handle-nw:active,:host ::ng-deep .resize-handle-ne:active,:host ::ng-deep .resize-handle-sw:active,:host ::ng-deep .resize-handle-se:active{transform:scale(.9)}:host ::ng-deep .resize-handle-nw{top:0;left:-6px;cursor:nw-resize}:host ::ng-deep .resize-handle-n{top:0;left:50%;transform:translate(-50%);cursor:n-resize}:host ::ng-deep .resize-handle-ne{top:0;right:-6px;cursor:ne-resize}:host ::ng-deep .resize-handle-w{top:50%;left:-6px;transform:translateY(-50%);cursor:w-resize}:host ::ng-deep .resize-handle-e{top:50%;right:-6px;transform:translateY(-50%);cursor:e-resize}:host ::ng-deep .resize-handle-sw{bottom:0;left:-6px;cursor:sw-resize}:host ::ng-deep .resize-handle-s{bottom:0;left:50%;transform:translate(-50%);cursor:s-resize}:host ::ng-deep .resize-handle-se{bottom:0;right:-6px;cursor:se-resize}:host ::ng-deep body.resizing{-webkit-user-select:none;user-select:none;cursor:crosshair}:host ::ng-deep body.resizing .ProseMirror{pointer-events:none}:host ::ng-deep body.resizing .ProseMirror .tiptap-image{pointer-events:none}:host ::ng-deep .image-size-info{position:absolute;bottom:-20px;left:50%;transform:translate(-50%);background:#000c;color:#fff;padding:2px 6px;border-radius:3px;font-size:11px;white-space:nowrap;opacity:0;transition:opacity .2s ease}:host ::ng-deep .image-container:hover .image-size-info{opacity:1}:host ::ng-deep .ProseMirror table{border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed;width:100%;border-radius:8px;overflow:hidden}:host ::ng-deep .ProseMirror table td,:host ::ng-deep .ProseMirror table th{border:none;border-right:1px solid #e2e8f0;border-bottom:1px solid #e2e8f0;box-sizing:border-box;min-width:1em;padding:8px 12px;position:relative;vertical-align:top;background:#fff}:host ::ng-deep .ProseMirror table td:first-child,:host ::ng-deep .ProseMirror table th:first-child{border-left:1px solid #e2e8f0}:host ::ng-deep .ProseMirror table tr:first-child td,:host ::ng-deep .ProseMirror table tr:first-child th{border-top:1px solid #e2e8f0}:host ::ng-deep .ProseMirror table tr:first-child th:first-child{border-top-left-radius:8px}:host ::ng-deep .ProseMirror table tr:first-child th:last-child{border-top-right-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:first-child{border-bottom-left-radius:8px}:host ::ng-deep .ProseMirror table tr:last-child td:last-child{border-bottom-right-radius:8px}:host ::ng-deep .ProseMirror table th{background:#f8f9fa;font-weight:600;color:#374151}:host ::ng-deep .ProseMirror table .selectedCell:after{background:#c8c8ff66;content:\"\";inset:0;pointer-events:none;position:absolute;z-index:2}:host ::ng-deep .ProseMirror table .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:#6366f1;opacity:0;transition:opacity .2s ease}:host ::ng-deep .ProseMirror table:hover .column-resize-handle{opacity:1}:host ::ng-deep .ProseMirror table .column-resize-handle:hover{background-color:#4f46e5}:host ::ng-deep .ProseMirror .tableWrapper{overflow-x:auto;margin:1em 0;border-radius:8px}:host ::ng-deep .ProseMirror .tableWrapper table{margin:0;border-radius:8px;min-width:600px;overflow:hidden}:host ::ng-deep .ProseMirror table p{margin:0}:host ::ng-deep .ProseMirror table .selectedCell{background-color:#6366f11a}:host ::ng-deep .ProseMirror table th{background-color:#f8f9fa;font-weight:600;color:#374151;text-align:left}:host ::ng-deep .ProseMirror table tbody tr:nth-child(2n){background-color:#fafbfc}:host ::ng-deep .ProseMirror table tbody tr:hover{background-color:#f1f5f9}\n"] }]
5032
5215
  }], ctorParameters: () => [] });
5033
5216
 
5034
- /**
5035
- * Clés des commandes dans l'ordre de création
5036
- */
5037
- const SLASH_COMMAND_KEYS = [
5038
- "heading1",
5039
- "heading2",
5040
- "heading3",
5041
- "bulletList",
5042
- "orderedList",
5043
- "blockquote",
5044
- "code",
5045
- "image",
5046
- "horizontalRule",
5047
- "table",
5048
- ];
5049
- /**
5050
- * Factory function pour créer les slash commands traduits
5051
- */
5052
- function createI18nSlashCommands(i18nService) {
5053
- const slashCommands = i18nService.slashCommands();
5054
- return [
5055
- {
5056
- title: slashCommands.heading1.title,
5057
- description: slashCommands.heading1.description,
5058
- icon: "format_h1",
5059
- keywords: slashCommands.heading1.keywords,
5060
- command: (editor) => editor.chain().focus().toggleHeading({ level: 1 }).run(),
5061
- },
5062
- {
5063
- title: slashCommands.heading2.title,
5064
- description: slashCommands.heading2.description,
5065
- icon: "format_h2",
5066
- keywords: slashCommands.heading2.keywords,
5067
- command: (editor) => editor.chain().focus().toggleHeading({ level: 2 }).run(),
5068
- },
5069
- {
5070
- title: slashCommands.heading3.title,
5071
- description: slashCommands.heading3.description,
5072
- icon: "format_h3",
5073
- keywords: slashCommands.heading3.keywords,
5074
- command: (editor) => editor.chain().focus().toggleHeading({ level: 3 }).run(),
5075
- },
5076
- {
5077
- title: slashCommands.bulletList.title,
5078
- description: slashCommands.bulletList.description,
5079
- icon: "format_list_bulleted",
5080
- keywords: slashCommands.bulletList.keywords,
5081
- command: (editor) => editor.chain().focus().toggleBulletList().run(),
5082
- },
5083
- {
5084
- title: slashCommands.orderedList.title,
5085
- description: slashCommands.orderedList.description,
5086
- icon: "format_list_numbered",
5087
- keywords: slashCommands.orderedList.keywords,
5088
- command: (editor) => editor.chain().focus().toggleOrderedList().run(),
5089
- },
5090
- {
5091
- title: slashCommands.blockquote.title,
5092
- description: slashCommands.blockquote.description,
5093
- icon: "format_quote",
5094
- keywords: slashCommands.blockquote.keywords,
5095
- command: (editor) => editor.chain().focus().toggleBlockquote().run(),
5096
- },
5097
- {
5098
- title: slashCommands.code.title,
5099
- description: slashCommands.code.description,
5100
- icon: "code",
5101
- keywords: slashCommands.code.keywords,
5102
- command: (editor) => editor.chain().focus().toggleCodeBlock().run(),
5103
- },
5104
- {
5105
- title: slashCommands.image.title,
5106
- description: slashCommands.image.description,
5107
- icon: "image",
5108
- keywords: slashCommands.image.keywords,
5109
- command: (editor) => {
5110
- // Créer un input file temporaire pour sélectionner une image
5111
- const input = document.createElement("input");
5112
- input.type = "file";
5113
- input.accept = "image/*";
5114
- input.style.display = "none";
5115
- input.addEventListener("change", async (e) => {
5116
- const file = e.target.files?.[0];
5117
- if (file && file.type.startsWith("image/")) {
5118
- try {
5119
- // Utiliser la méthode de compression unifiée
5120
- const canvas = document.createElement("canvas");
5121
- const ctx = canvas.getContext("2d");
5122
- const img = new Image();
5123
- img.onload = () => {
5124
- // Vérifier les dimensions (max 1920x1080)
5125
- const maxWidth = 1920;
5126
- const maxHeight = 1080;
5127
- let { width, height } = img;
5128
- // Redimensionner si nécessaire
5129
- if (width > maxWidth || height > maxHeight) {
5130
- const ratio = Math.min(maxWidth / width, maxHeight / height);
5131
- width *= ratio;
5132
- height *= ratio;
5133
- }
5134
- canvas.width = width;
5135
- canvas.height = height;
5136
- // Dessiner l'image redimensionnée
5137
- ctx?.drawImage(img, 0, 0, width, height);
5138
- // Convertir en base64 avec compression
5139
- canvas.toBlob((blob) => {
5140
- if (blob) {
5141
- const reader = new FileReader();
5142
- reader.onload = (e) => {
5143
- const base64 = e.target?.result;
5144
- if (base64) {
5145
- // Utiliser setResizableImage avec toutes les propriétés
5146
- editor
5147
- .chain()
5148
- .focus()
5149
- .setResizableImage({
5150
- src: base64,
5151
- alt: file.name,
5152
- title: `${file.name} (${Math.round(width)}×${Math.round(height)})`,
5153
- width: Math.round(width),
5154
- height: Math.round(height),
5155
- })
5156
- .run();
5157
- }
5158
- };
5159
- reader.readAsDataURL(blob);
5160
- }
5161
- }, file.type, 0.8 // qualité de compression
5162
- );
5163
- };
5164
- img.onerror = () => {
5165
- console.error(i18nService.editor().imageLoadError);
5166
- };
5167
- img.src = URL.createObjectURL(file);
5168
- }
5169
- catch (error) {
5170
- console.error("Error uploading image:", error);
5171
- }
5172
- }
5173
- document.body.removeChild(input);
5174
- });
5175
- document.body.appendChild(input);
5176
- input.click();
5177
- },
5178
- },
5179
- {
5180
- title: slashCommands.horizontalRule.title,
5181
- description: slashCommands.horizontalRule.description,
5182
- icon: "horizontal_rule",
5183
- keywords: slashCommands.horizontalRule.keywords,
5184
- command: (editor) => editor.chain().focus().setHorizontalRule().run(),
5185
- },
5186
- {
5187
- title: slashCommands.table.title,
5188
- description: slashCommands.table.description,
5189
- icon: "table_view",
5190
- keywords: slashCommands.table.keywords,
5191
- command: (editor) => editor.chain().focus().insertTable({ rows: 3, cols: 3 }).run(),
5192
- },
5193
- ];
5194
- }
5195
- /**
5196
- * Fonction utilitaire pour filtrer les slash commands selon les commandes actives
5197
- * Utilise le service i18n injecté en interne
5198
- */
5199
- function filterSlashCommands(activeCommands) {
5200
- // Injecter le service i18n en interne
5201
- const i18nService = inject(TiptapI18nService);
5202
- const allCommands = createI18nSlashCommands(i18nService);
5203
- return allCommands.filter((command, index) => {
5204
- const commandKey = SLASH_COMMAND_KEYS[index];
5205
- return commandKey && activeCommands.has(commandKey);
5206
- });
5207
- }
5208
-
5209
5217
  /*
5210
5218
  * Public API Surface of tiptap-editor
5211
5219
  */
@@ -5215,5 +5223,5 @@ function filterSlashCommands(activeCommands) {
5215
5223
  * Generated bundle index. Do not edit.
5216
5224
  */
5217
5225
 
5218
- export { AngularTiptapEditorComponent, DEFAULT_BUBBLE_MENU_CONFIG, DEFAULT_CELL_MENU_CONFIG, DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, DEFAULT_SLASH_COMMANDS, DEFAULT_TABLE_MENU_CONFIG, DEFAULT_TOOLBAR_CONFIG, EditorCommandsService, ImageService, NoopValueAccessorDirective, SLASH_COMMAND_KEYS, TiptapI18nService, createI18nSlashCommands, filterSlashCommands };
5226
+ export { AngularTiptapEditorComponent, DEFAULT_BUBBLE_MENU_CONFIG, DEFAULT_CELL_MENU_CONFIG, DEFAULT_IMAGE_BUBBLE_MENU_CONFIG, DEFAULT_SLASH_COMMANDS$1 as DEFAULT_SLASH_COMMANDS, DEFAULT_TABLE_MENU_CONFIG, DEFAULT_TOOLBAR_CONFIG, EditorCommandsService, ImageService, NoopValueAccessorDirective, SLASH_COMMAND_KEYS, TiptapI18nService, createI18nSlashCommands, filterSlashCommands };
5219
5227
  //# sourceMappingURL=flogeez-angular-tiptap-editor.mjs.map