diff --git a/package.json b/package.json
index 20590fcbe..775f3508d 100644
--- a/package.json
+++ b/package.json
@@ -42,12 +42,14 @@
"@primeng/themes": "^19.0.9",
"ace-builds": "^1.42.0",
"chart.js": "^4.4.9",
+ "diff": "^8.0.2",
"ngx-markdown-editor": "^5.3.4",
"primeflex": "^4.0.0",
"primeicons": "^7.0.0",
"primeng": "^19.0.9",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
+ "turndown": "^7.2.0",
"zone.js": "~0.15.0"
},
"devDependencies": {
@@ -58,6 +60,7 @@
"@commitlint/config-conventional": "^19.7.1",
"@types/jasmine": "~5.1.0",
"@types/jest": "^29.5.14",
+ "@types/turndown": "^5.0.5",
"angular-eslint": "19.1.0",
"angularx-qrcode": "^19.0.0",
"eslint": "^9.20.0",
diff --git a/src/app/features/project/wiki/components/compare-section/compare-section.component.html b/src/app/features/project/wiki/components/compare-section/compare-section.component.html
index 9351a9279..6a425c080 100644
--- a/src/app/features/project/wiki/components/compare-section/compare-section.component.html
+++ b/src/app/features/project/wiki/components/compare-section/compare-section.component.html
@@ -19,10 +19,8 @@
{{ 'project.wiki.compare' | translate }}
styleClass="select-version"
/>
-
-
- {{ versionContent() }}
-
+
+
}
diff --git a/src/app/features/project/wiki/components/compare-section/compare-section.component.ts b/src/app/features/project/wiki/components/compare-section/compare-section.component.ts
index b0677e0ed..b11bc130d 100644
--- a/src/app/features/project/wiki/components/compare-section/compare-section.component.ts
+++ b/src/app/features/project/wiki/components/compare-section/compare-section.component.ts
@@ -9,6 +9,9 @@ import { FormsModule } from '@angular/forms';
import { WikiVersion } from '../../models';
+import * as Diff from 'diff';
+import TurndownService from 'turndown';
+
@Component({
selector: 'osf-compare-section',
imports: [PanelModule, Select, FormsModule, TranslatePipe, Skeleton],
@@ -19,6 +22,7 @@ import { WikiVersion } from '../../models';
export class CompareSectionComponent {
versions = input.required();
versionContent = input.required();
+ previewContent = input.required();
isLoading = input.required();
selectVersion = output();
@@ -26,7 +30,7 @@ export class CompareSectionComponent {
mappedVersions = computed(() => [
...this.versions().map((version, index) => {
- const labelPrefix = index === 0 ? '(Current)' : `(${index})`;
+ const labelPrefix = index === 0 ? '(Current)' : `(${this.versions().length - index})`;
return {
label: `${labelPrefix} ${version.createdBy}: (${new Date(version.createdAt).toLocaleString()})`,
value: version.id,
@@ -34,13 +38,41 @@ export class CompareSectionComponent {
}),
]);
+ content = computed(() => {
+ const changes = Diff.diffWords(
+ this.convertHtmlToMarkdown(this.versionContent()),
+ this.convertHtmlToMarkdown(this.previewContent())
+ );
+ return changes
+ .map((change) => {
+ if (change.added) {
+ return `${change.value}`;
+ } else if (change.removed) {
+ return `${change.value}`;
+ }
+ return change.value;
+ })
+ .join('');
+ });
+
constructor() {
effect(() => {
- this.versions();
- this.selectedVersion = null;
+ this.selectedVersion = this.versions()[0].id;
+ this.selectVersion.emit(this.selectedVersion);
});
}
-
+ convertHtmlToMarkdown(html: string): string {
+ const turndownService = new TurndownService({
+ headingStyle: 'atx',
+ emDelimiter: '*',
+ strongDelimiter: '**',
+ hr: '---',
+ linkStyle: 'inlined',
+ bulletListMarker: '-',
+ codeBlockStyle: 'indented',
+ });
+ return turndownService.turndown(html);
+ }
onVersionChange(versionId: string): void {
this.selectedVersion = versionId;
this.selectVersion.emit(versionId);
diff --git a/src/app/features/project/wiki/components/view-section/view-section.component.ts b/src/app/features/project/wiki/components/view-section/view-section.component.ts
index d7bafcb95..73f813414 100644
--- a/src/app/features/project/wiki/components/view-section/view-section.component.ts
+++ b/src/app/features/project/wiki/components/view-section/view-section.component.ts
@@ -38,7 +38,7 @@ export class ViewSectionComponent {
mappedVersions = computed(() => [
this.previewOption,
...this.versions().map((version, index) => {
- const labelPrefix = index === 0 ? '(Current)' : `(${index})`;
+ const labelPrefix = index === 0 ? '(Current)' : `(${this.versions().length - index})`;
return {
label: `${labelPrefix} ${version.createdBy}: (${new Date(version.createdAt).toLocaleString()})`,
value: version.id,
diff --git a/src/app/features/project/wiki/wiki.component.html b/src/app/features/project/wiki/wiki.component.html
index a74076e23..a7ada9fbd 100644
--- a/src/app/features/project/wiki/wiki.component.html
+++ b/src/app/features/project/wiki/wiki.component.html
@@ -48,6 +48,7 @@
@if (wikiModes().compare) {