Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5,280 changes: 2,610 additions & 2,670 deletions package-lock.json

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,25 @@
"angular-rte"
],
"dependencies": {
"@angular/animations": "^20.3.16",
"@angular/common": "^20.3.16",
"@angular/compiler": "^20.3.16",
"@angular/core": "^20.3.16",
"@angular/forms": "^20.3.16",
"@angular/platform-browser": "^20.3.16",
"@angular/platform-browser-dynamic": "^20.3.16",
"@angular/platform-server": "^20.3.16",
"@angular/router": "^20.3.16",
"@angular/ssr": "^20.3.16",
"@angular/animations": "^21.1.4",
"@angular/common": "^21.1.4",
"@angular/compiler": "^21.1.4",
"@angular/core": "^21.1.4",
"@angular/forms": "^21.1.4",
"@angular/platform-browser": "^21.1.4",
"@angular/platform-browser-dynamic": "^21.1.4",
"@angular/platform-server": "^21.1.4",
"@angular/router": "^21.1.4",
"@angular/ssr": "^21.1.4",
"express": "^4.18.2",
"rxjs": "~7.8.0",
"tslib": "^2.3.1",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular/build": "^20.3.16",
"@angular/cli": "^20.3.16",
"@angular/compiler-cli": "^20.3.16",
"@angular/build": "^21.1.4",
"@angular/cli": "^21.1.4",
"@angular/compiler-cli": "^21.1.4",
"@codemirror/lang-javascript": "^6.2.3",
"@commitlint/cli": "^19.8.0",
"@commitlint/config-conventional": "^19.8.0",
Expand All @@ -59,7 +59,7 @@
"@types/jasmine": "~5.1.0",
"@types/node": "^25.2.3",
"@types/trusted-types": "~2.0.7",
"angular-eslint": "20.7.0",
"angular-eslint": "21.2.0",
"codemirror": "^6.0.1",
"eslint": "^9.28.0",
"eslint-config-pegasus": "^6.0.2",
Expand All @@ -72,7 +72,7 @@
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"lint-staged": "^15.5.1",
"ng-packagr": "^20.3.2",
"ng-packagr": "^21.1.0",
"picocolors": "^1.1.1",
"prettier": "^3.5.3",
"prettier-plugin-astro": "^0.14.1",
Expand Down
14 changes: 8 additions & 6 deletions projects/demo/src/app/editor.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
<img src="/ngx-editor.svg" alt="ngx-editor" />
<div class="subtitle">Rich Text Editor for angular using ProseMirror</div>
</div>
<div class="badges" *ngIf="!isDevMode">
<img src="https://badgen.net/npm/v/ngx-editor" alt="version" />
<img src="https://badgen.net/npm/dm/ngx-editor" alt="downloads per month " />
<img src="https://badgen.net/npm/dt/ngx-editor" alt="total downloads" />
<img src="https://badgen.net/npm/license/ngx-editor" alt="license" />
</div>
@if (!isDevMode) {
<div class="badges">
<img src="https://badgen.net/npm/v/ngx-editor" alt="version" />
<img src="https://badgen.net/npm/dm/ngx-editor" alt="downloads per month " />
<img src="https://badgen.net/npm/dt/ngx-editor" alt="total downloads" />
<img src="https://badgen.net/npm/license/ngx-editor" alt="license" />
</div>
}
</div>

<div>
Expand Down
7 changes: 3 additions & 4 deletions projects/demo/src/app/editor.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CommonModule } from '@angular/common';

import { Component, OnDestroy, OnInit, ViewEncapsulation, isDevMode } from '@angular/core';
import { AbstractControl, FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';

Expand All @@ -24,14 +24,13 @@ import schema from './schema';
encapsulation: ViewEncapsulation.None,
standalone: true,
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
NgxEditorComponent,
NgxEditorMenuComponent,
NgxEditorFloatingMenuComponent,
AppCustomMenuComponent,
],
AppCustomMenuComponent
],
})
export class EditorComponent implements OnInit, OnDestroy {
isDevMode = isDevMode();
Expand Down
3 changes: 2 additions & 1 deletion projects/demo/src/main.server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { provideZoneChangeDetection } from "@angular/core";
import { bootstrapApplication, BootstrapContext } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { config } from './app/app.config.server';

const bootstrap = (context: BootstrapContext) => bootstrapApplication(AppComponent, config, context);
const bootstrap = (context: BootstrapContext) => bootstrapApplication(AppComponent, {...config, providers: [provideZoneChangeDetection(), ...config.providers]}, context);

export default bootstrap;
2 changes: 1 addition & 1 deletion projects/ngx-editor/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"FEATURE23-FORK": "version, repository, bugs, homepage modified; name renamed to @feature23/ngx-editor at build time via scripts/postbuild.js",
"name": "ngx-editor",
"version": "20.0.0",
"version": "21.0.0",
"description": "The Rich Text Editor for Angular, Built on ProseMirror",
"license": "MIT",
"type": "module",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<span class="NgxEditor__ImageWrapper" [ngClass]="{ 'NgxEditor__Resizer--Active': selected }" [style.width]="outerWidth">
<span class="NgxEditor__ResizeHandle" *ngIf="selected">
<span class="NgxEditor__ResizeHandle--TL" (mousedown)="startResizing($event, 'left')"></span>
<span class="NgxEditor__ResizeHandle--TR" (mousedown)="startResizing($event, 'right')"></span>
<span class="NgxEditor__ResizeHandle--BL" (mousedown)="startResizing($event, 'left')"></span>
<span class="NgxEditor__ResizeHandle--BR" (mousedown)="startResizing($event, 'right')"></span>
</span>
@if (selected) {
<span class="NgxEditor__ResizeHandle">
<span class="NgxEditor__ResizeHandle--TL" (mousedown)="startResizing($event, 'left')"></span>
<span class="NgxEditor__ResizeHandle--TR" (mousedown)="startResizing($event, 'right')"></span>
<span class="NgxEditor__ResizeHandle--BL" (mousedown)="startResizing($event, 'left')"></span>
<span class="NgxEditor__ResizeHandle--BR" (mousedown)="startResizing($event, 'right')"></span>
</span>
}
<img [src]="src" [alt]="alt" [title]="title" #imgEl />
</span>
10 changes: 5 additions & 5 deletions projects/ngx-editor/src/lib/editor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
SimpleChanges,
ViewChild,
ViewEncapsulation,
inject
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Subject } from 'rxjs';
Expand All @@ -38,11 +39,10 @@ import { HTML, isHtml } from './trustedTypesUtil';
encapsulation: ViewEncapsulation.None,
})
export class NgxEditorComponent implements ControlValueAccessor, OnInit, OnChanges, OnDestroy {
constructor(
private renderer: Renderer2,
private injector: Injector,
private elementRef: ElementRef<HTMLElement>,
) { }
private renderer = inject(Renderer2);
private injector = inject(Injector);
private elementRef = inject<ElementRef<HTMLElement>>(ElementRef);


@ViewChild('ngxEditor', { static: true }) private ngxEditor: ElementRef;

Expand Down
6 changes: 4 additions & 2 deletions projects/ngx-editor/src/lib/editor.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable, Optional } from '@angular/core';
import { Injectable, inject } from '@angular/core';

import { NgxEditorConfig } from './types';
import Locals from './Locals';
Expand All @@ -12,7 +12,9 @@ import { HTML } from './trustedTypesUtil';
export class NgxEditorService {
config: NgxEditorServiceConfig;

constructor(@Optional() config?: NgxEditorServiceConfig) {
constructor() {
const config = inject(NgxEditorServiceConfig, { optional: true });

this.config = config;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
<ng-container *ngFor="let toolbarItem of toolbar; let lastToolbarItem = last; trackBy: trackByIndex">
<ng-container *ngFor="let item of toolbarItem; let lastItem = last; trackBy: trackByIndex">
<button
type="button"
class="NgxBubbleMenu__Icon"
*ngIf="toggleCommands.includes(item)"
[ngClass]="{
'NgxBubbleMenu__Icon--Active': this.activeItems.includes(item),
'NgxEditor--Disabled': !this.execulableItems.includes(item)
}"
(mousedown)="onClick($event, item)"
[title]="getTitle(item) | async"
[innerHTML]="getIcon(item)"
></button>
<div class="NgxBubbleMenu__Seperator" *ngIf="lastItem && !lastToolbarItem"></div>
</ng-container>
</ng-container>
@for (toolbarItem of toolbar; track $index; let lastToolbarItem = $last) {
@for (item of toolbarItem; track $index; let lastItem = $last) {
@if (toggleCommands.includes(item)) {
<button
type="button"
class="NgxBubbleMenu__Icon"
[ngClass]="{
'NgxBubbleMenu__Icon--Active': this.activeItems.includes(item),
'NgxEditor--Disabled': !this.execulableItems.includes(item),
}"
(mousedown)="onClick($event, item)"
[title]="getTitle(item) | async"
[innerHTML]="getIcon(item)"
></button>
}
@if (lastItem && !lastToolbarItem) {
<div class="NgxBubbleMenu__Seperator"></div>
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Component, Input, OnDestroy, OnInit, inject } from '@angular/core';
import { SafeHtml } from '@angular/platform-browser';
import { EditorView } from 'prosemirror-view';
import { Observable, Subscription } from 'rxjs';
Expand All @@ -18,10 +18,9 @@ import { ToggleCommands } from '../MenuCommands';
providers: [SanitizeHtmlPipe],
})
export class BubbleComponent implements OnInit, OnDestroy {
constructor(
private sanitizeHTML: SanitizeHtmlPipe,
private ngxeService: NgxEditorService,
) {}
private sanitizeHTML = inject(SanitizeHtmlPipe);
private ngxeService = inject(NgxEditorService);


private get view(): EditorView {
return this.editor.view;
Expand Down Expand Up @@ -62,10 +61,6 @@ export class BubbleComponent implements OnInit, OnDestroy {
return this.ngxeService.locals.get(name);
}

trackByIndex(index: number): number {
return index;
}

onClick(e: MouseEvent, commandName: TBItems): void {
e.preventDefault();
e.stopPropagation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,31 @@
[ariaLabel]="title | async"
></button>

<div *ngIf="showPopup" class="NgxEditor__Popup">
<div *ngFor="let colorGroup of presets; trackBy: trackByIndex" class="NgxEditor__ColorContainer">
@if (showPopup) {
<div class="NgxEditor__Popup">
@for (colorGroup of presets; track $index) {
<div class="NgxEditor__ColorContainer">
@for (color of colorGroup; track $index) {
<button
class="NgxEditor__Color"
[ngStyle]="{ backgroundColor: color, color: getContrastYIQ(color) }"
[title]="color"
(mousedown)="onColorSelectMouseClick($event, color)"
(keydown.enter)="onColorSelectKeydown(color)"
(keydown.space)="onColorSelectKeydown(color)"
[ngClass]="{ 'NgxEditor__Color--Active': activeColors.includes(color) }"
></button>
}
</div>
}
<button
class="NgxEditor__Color"
*ngFor="let color of colorGroup; trackBy: trackByIndex"
[ngStyle]="{ backgroundColor: color, color: getContrastYIQ(color) }"
[title]="color"
(mousedown)="onColorSelectMouseClick($event, color)"
(keydown.enter)="onColorSelectKeydown(color)"
(keydown.space)="onColorSelectKeydown(color)"
[ngClass]="{ 'NgxEditor__Color--Active': activeColors.includes(color) }"
></button>
class="NgxEditor__MenuItem--Button"
(mousedown)="onRemoveMouseClick($event)"
(keydown.enter)="onRemoveKeydown()"
(keydown.space)="onRemoveKeydown()"
[disabled]="!isActive"
>
{{ getLabel('remove') | async }}
</button>
</div>

<button
class="NgxEditor__MenuItem--Button"
(mousedown)="onRemoveMouseClick($event)"
(keydown.enter)="onRemoveKeydown()"
(keydown.space)="onRemoveKeydown()"
[disabled]="!isActive"
>
{{ getLabel('remove') | async }}
</button>
</div>
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import {
Component, ElementRef, HostListener, Input, OnDestroy, OnInit,
Component,
ElementRef,
HostListener,
Input,
OnDestroy,
OnInit,
inject
} from '@angular/core';
import { EditorView } from 'prosemirror-view';
import { Observable, Subscription } from 'rxjs';
Expand All @@ -20,15 +26,13 @@ type Command = typeof TextColor | typeof TextBackgroundColor;
imports: [AsyncPipe, CommonModule, SanitizeHtmlPipe],
})
export class ColorPickerComponent implements OnInit, OnDestroy {
private el = inject(ElementRef);
private menuService = inject(MenuService);
private ngxeService = inject(NgxEditorService);

@Input() presets: string[][];
@Input() type: string;

constructor(
private el: ElementRef,
private menuService: MenuService,
private ngxeService: NgxEditorService,
) {}

get title(): Observable<string> {
return this.getLabel(this.type === 'text_color' ? 'text_color' : 'background_color');
}
Expand Down Expand Up @@ -107,10 +111,6 @@ export class ColorPickerComponent implements OnInit, OnDestroy {
this.remove();
}

trackByIndex(index: number): number {
return index;
}

selectColor(color: string): void {
const { state, dispatch } = this.editorView;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,25 @@
{{ getName(activeItem || group) | async }}
</button>

<div class="NgxEditor__Dropdown--DropdownMenu" *ngIf="isDropdownOpen" role="listbox">
<button
type="button"
class="NgxEditor__Dropdown--Item"
*ngFor="let item of items; trackBy: trackByIndex"
(mousedown)="onDropdownItemMouseClick($event, item)"
(keydown.enter)="onDropdownItemKeydown($event, item)"
(keydown.space)="onDropdownItemKeydown($event, item)"
[ngClass]="{
'NgxEditor__Dropdown--Active': item === activeItem,
'NgxEditor--Disabled': disabledItems.includes(item),
}"
[ariaLabel]="getName(item) | async"
role="option"
[attr.aria-selected]="item === activeItem"
>
{{ getName(item) | async }}
</button>
</div>
@if (isDropdownOpen) {
<div class="NgxEditor__Dropdown--DropdownMenu" role="listbox">
@for (item of items; track $index) {
<button
type="button"
class="NgxEditor__Dropdown--Item"
(mousedown)="onDropdownItemMouseClick($event, item)"
(keydown.enter)="onDropdownItemKeydown($event, item)"
(keydown.space)="onDropdownItemKeydown($event, item)"
[ngClass]="{
'NgxEditor__Dropdown--Active': item === activeItem,
'NgxEditor--Disabled': disabledItems.includes(item),
}"
[ariaLabel]="getName(item) | async"
role="option"
[attr.aria-selected]="item === activeItem"
>
{{ getName(item) | async }}
</button>
}
</div>
}
Loading