WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 4310066

Browse files
authored
Add createDiffView wrapper (#5825)
* add `createDiffView` wrapper * refactor diff handling: introduce `DiffViewOptions`, streamline API, and update tests * refactor: rename `DiffView` to `SplitDiffView`, enhance typings, and update usage across modules; add diff ext package tests * fix: update references to `SplitDiffView` after module rename * fix: ensure proper cleanup of editors in `InlineDiffView` and detach functionality; add destroy calls for `diffView`
1 parent 7e53851 commit 4310066

File tree

15 files changed

+612
-369
lines changed

15 files changed

+612
-369
lines changed

ace-internal.d.ts

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ export namespace Ace {
2929
type Config = typeof import("./src/config");
3030
type GutterTooltip = import( "./src/mouse/default_gutter_handler").GutterTooltip;
3131
type GutterKeyboardEvent = import( "./src/keyboard/gutter_handler").GutterKeyboardEvent;
32-
type HoverTooltip = import("ace-code/src/tooltip").HoverTooltip;
33-
type Tooltip = import("ace-code/src/tooltip").Tooltip;
34-
type PopupManager = import("ace-code/src/tooltip").PopupManager;
35-
type TextInput = import("ace-code/src/keyboard/textinput").TextInput;
32+
type HoverTooltip = import("./src/tooltip").HoverTooltip;
33+
type Tooltip = import("./src/tooltip").Tooltip;
34+
type TextInput = import("./src/keyboard/textinput").TextInput;
35+
type DiffChunk = import("./src/ext/diff/base_diff_view").DiffChunk;
3636

3737
type AfterLoadCallback = (err: Error | null, module: unknown) => void;
3838
type LoaderFunction = (moduleName: string, afterLoad: AfterLoadCallback) => void;
@@ -1313,28 +1313,6 @@ export namespace Ace {
13131313
setLabel?: boolean;
13141314
inline?: boolean;
13151315
}
1316-
1317-
export interface TextAreaOptions {
1318-
/** Programming language mode for syntax highlighting (e.g., "javascript", "html", "css") */
1319-
mode?: string;
1320-
/** Visual theme for the editor appearance (e.g., "textmate", "monokai", "eclipse") */
1321-
theme?: string;
1322-
/** Line wrapping behavior - "off", "free", or specific column number like "40", "80" */
1323-
wrap?: string | number;
1324-
/** Font size in CSS units (e.g., "12px", "14px", "16px") */
1325-
fontSize?: string;
1326-
/** Whether to display the line number gutter on the left side */
1327-
showGutter?: boolean | string;
1328-
/** Keyboard handler/bindings to use - "ace", "vim", or "emacs" */
1329-
keybindings?: string;
1330-
/** Whether to show the print margin indicator line */
1331-
showPrintMargin?: boolean | string;
1332-
/** Whether to use soft tabs (spaces) instead of hard tabs */
1333-
useSoftTabs?: boolean | string;
1334-
/** Whether to show invisible characters like spaces and tabs */
1335-
showInvisibles?: boolean | string;
1336-
}
1337-
13381316
}
13391317

13401318

@@ -1671,3 +1649,8 @@ declare module "./src/mouse/default_gutter_handler" {
16711649
}
16721650
}
16731651

1652+
declare module "./src/ext/diff/base_diff_view" {
1653+
export interface BaseDiffView extends Ace.OptionsProvider<import("ace-code/src/ext/diff").DiffViewOptions> {
1654+
}
1655+
}
1656+

ace.d.ts

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ declare module "ace-code" {
4040
type GutterKeyboardEvent = import("ace-code/src/keyboard/gutter_handler").GutterKeyboardEvent;
4141
type HoverTooltip = import("ace-code/src/tooltip").HoverTooltip;
4242
type Tooltip = import("ace-code/src/tooltip").Tooltip;
43-
type PopupManager = import("ace-code/src/tooltip").PopupManager;
4443
type TextInput = import("ace-code/src/keyboard/textinput").TextInput;
44+
type DiffChunk = import("ace-code/src/ext/diff/base_diff_view").DiffChunk;
4545
type AfterLoadCallback = (err: Error | null, module: unknown) => void;
4646
type LoaderFunction = (moduleName: string, afterLoad: AfterLoadCallback) => void;
4747
export interface ConfigOptions {
@@ -1050,26 +1050,6 @@ declare module "ace-code" {
10501050
setLabel?: boolean;
10511051
inline?: boolean;
10521052
}
1053-
export interface TextAreaOptions {
1054-
/** Programming language mode for syntax highlighting (e.g., "javascript", "html", "css") */
1055-
mode?: string;
1056-
/** Visual theme for the editor appearance (e.g., "textmate", "monokai", "eclipse") */
1057-
theme?: string;
1058-
/** Line wrapping behavior - "off", "free", or specific column number like "40", "80" */
1059-
wrap?: string | number;
1060-
/** Font size in CSS units (e.g., "12px", "14px", "16px") */
1061-
fontSize?: string;
1062-
/** Whether to display the line number gutter on the left side */
1063-
showGutter?: boolean | string;
1064-
/** Keyboard handler/bindings to use - "ace", "vim", or "emacs" */
1065-
keybindings?: string;
1066-
/** Whether to show the print margin indicator line */
1067-
showPrintMargin?: boolean | string;
1068-
/** Whether to use soft tabs (spaces) instead of hard tabs */
1069-
useSoftTabs?: boolean | string;
1070-
/** Whether to show invisible characters like spaces and tabs */
1071-
showInvisibles?: boolean | string;
1072-
}
10731053
}
10741054
export const config: typeof import("ace-code/src/config");
10751055
export function edit(el?: string | (HTMLElement & {

demo/diff/index.html

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,16 @@
6565
});
6666

6767
require([
68-
"ace/ext/diff/diff_view",
69-
"ace/ext/diff/inline_diff_view",
68+
"ace/ext/diff/split_diff_view",
69+
"ace/ext/diff/inline_diff_view",
7070
"demo/kitchen-sink/util",
7171
"demo/kitchen-sink/layout",
7272
"ace/ext/diff/providers/default",
7373
"ace/ext/options",
7474
"ace/ext/menu_tools/overlay_page",
7575
], function () {
7676
var {InlineDiffView} = require("ace/ext/diff/inline_diff_view");
77-
var {DiffView} = require("ace/ext/diff/diff_view");
77+
var {SplitDiffView} = require("ace/ext/diff/split_diff_view");
7878
var {DiffProvider} = require("ace/ext/diff/providers/default");
7979
var {OptionPanel, optionGroups} = require("ace/ext/options")
8080
var {buildDom} = require("ace/lib/dom");
@@ -121,26 +121,24 @@
121121
case "inlineA":
122122
diffView = new InlineDiffView({
123123
editorA, editorB,
124-
showSideA: true
125124
});
126125
if (!debugInline) editorB.container.style.display = "none";
127126
editorA.container.style.display = "";
128127
break;
129128
case "inlineB":
130129
diffView = new InlineDiffView({
131130
editorA, editorB,
132-
showSideA: false
131+
inline: "b"
133132
});
134133
editorB.container.style.display = "";
135134
if (!debugInline) editorA.container.style.display = "none";
136135
break;
137136
case "split":
138-
diffView = new DiffView({editorA, editorB});
137+
diffView = new SplitDiffView({editorA, editorB});
139138
editorA.container.style.display = "";
140139
editorB.container.style.display = "";
141140
break;
142141
case "off":
143-
diffView.detach("off");
144142
diffView = undefined;
145143
editorA.container.style.display = "";
146144
editorB.container.style.display = "";

demo/kitchen-sink/demo.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var Range = require("ace/range").Range;
3333

3434
var whitespace = require("ace/ext/whitespace");
3535

36+
var createDiffView = require("../../src/ext/diff").createDiffView;
3637

3738

3839
var doclist = require("./doclist");
@@ -323,6 +324,7 @@ window.onresize = onResize;
323324
onResize();
324325

325326
/*********** options panel ***************************/
327+
var diffView;
326328
doclist.history = doclist.docs.map(function(doc) {
327329
return doc.name;
328330
});
@@ -355,6 +357,14 @@ doclist.pickDocument = function(name) {
355357
whitespace.detectIndentation(session);
356358
optionsPanel.render();
357359
env.editor.focus();
360+
if (diffView) {
361+
diffView.detach()
362+
diffView = createDiffView({
363+
inline: "b",
364+
editorB: editor,
365+
valueA: editor.getValue()
366+
});
367+
}
358368
});
359369
};
360370

@@ -365,6 +375,7 @@ var optionsPanel = env.optionsPanel = new OptionPanel(env.editor);
365375

366376
var originalAutocompleteCommand = null;
367377

378+
368379
optionsPanel.add({
369380
Main: {
370381
Document: {
@@ -406,6 +417,31 @@ optionsPanel.add({
406417
? "Below"
407418
: "Beside";
408419
}
420+
},
421+
"Show diffs": {
422+
position: 0,
423+
type: "buttonBar",
424+
path: "diffView",
425+
values: ["None", "Inline"],
426+
onchange: function (value) {
427+
if (value === "Inline" && !diffView) {
428+
diffView = createDiffView({
429+
inline: "b",
430+
editorB: editor,
431+
valueA: editor.getValue()
432+
});
433+
}
434+
else if (value === "None") {
435+
if (diffView) {
436+
diffView.detach();
437+
diffView = null;
438+
}
439+
}
440+
},
441+
getValue: function() {
442+
return !diffView ? "None"
443+
: "Inline";
444+
}
409445
}
410446
},
411447
More: {

demo/test_ace_builds/index.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ import "../../src/test/mockdom.js";
66
var HoverTooltip = ace.require("ace/tooltip").HoverTooltip;
77
import "ace-builds/src-noconflict/mode-javascript";
88
import "ace-builds/src-noconflict/theme-monokai";
9+
import {DiffViewOptions } from "ace-builds/src-noconflict/ext-diff";
10+
import "ace-builds/src-noconflict/ext-diff";
11+
const diff = ace.require("ace/ext/diff");
912

1013
const MarkerGroup = ace.require("ace/marker_group").MarkerGroup;
1114
const MouseEvent = ace.require("ace/mouse/mouse_event").MouseEvent;
1215
var Tooltip = ace.require("ace/tooltip").Tooltip;
13-
var popupManager: Ace.PopupManager = ace.require("ace/tooltip").popupManager;
16+
var popupManager = ace.require("ace/tooltip").popupManager;
1417

1518
const editor = ace.edit(null); // should not be an error
1619
editor.setTheme("ace/theme/monokai");
@@ -63,4 +66,18 @@ tooltip.show('hello');
6366

6467
popupManager.addPopup(tooltip);
6568

66-
editor.destroy && editor.destroy();
69+
editor.destroy && editor.destroy();
70+
71+
const diffViewOptions: DiffViewOptions = {
72+
maxDiffs: 1000,
73+
folding: true
74+
}
75+
76+
var diffView = diff.createDiffView({
77+
valueB: "test",
78+
inline: "b"
79+
}, diffViewOptions);
80+
81+
diffView.setProvider(new diff.DiffProvider());
82+
83+
diffView.destroy();

demo/test_package/index.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import "../../src/test/mockdom.js";
1616
import {tokenize} from "ace-code/src/ext/simple_tokenizer";
1717
import {JavaScriptHighlightRules} from "ace-code/src/mode/javascript_highlight_rules";
1818
import {highlight} from "ace-code/src/ext/static_highlight";
19+
import {createDiffView, DiffProvider, DiffViewOptions} from "ace-code/src/ext/diff";
1920

2021
// TODO this does not work in node
2122
// import "ace-code/esm-resolver";
@@ -155,4 +156,18 @@ editor.commands.on('afterExec', ({editor, command}) => {
155156

156157
editor.commands.on('exec', ({editor, command}) => {
157158
console.log(editor.getValue(), command.name);
158-
});
159+
});
160+
161+
const diffViewOptions: DiffViewOptions = {
162+
maxDiffs: 1000,
163+
folding: true
164+
}
165+
166+
var diffView = createDiffView({
167+
valueB: "test",
168+
inline: "b"
169+
}, diffViewOptions);
170+
171+
diffView.setProvider(new DiffProvider());
172+
173+
diffView.destroy();

src/ext/diff.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* ## Diff extension
3+
*
4+
* Provides side-by-side and inline diff view capabilities for comparing code differences between two versions.
5+
* Supports visual highlighting of additions, deletions, and modifications with customizable diff providers
6+
* and rendering options. Includes features for synchronized scrolling, line number alignment, and
7+
* various diff computation algorithms.
8+
*
9+
* **Components:**
10+
* - `InlineDiffView`: Single editor view showing changes inline with markers
11+
* - `SplitDiffView`: Side-by-side comparison view with two synchronized editors
12+
* - `DiffProvider`: Configurable algorithms for computing differences
13+
*
14+
* **Usage:**
15+
* ```javascript
16+
* const diffView = createDiffView({
17+
* valueA: originalContent,
18+
* valueB: modifiedContent,
19+
* inline: false // or 'a'/'b' for inline view
20+
* });
21+
* ```
22+
*
23+
* @module
24+
*/
25+
26+
var InlineDiffView = require("./diff/inline_diff_view").InlineDiffView;
27+
var SplitDiffView = require("./diff/split_diff_view").SplitDiffView;
28+
var DiffProvider = require("./diff/providers/default").DiffProvider;
29+
30+
/**
31+
* Interface representing a model for handling differences between two views or states.
32+
* @typedef {Object} DiffModel
33+
* @property {import("../editor").Editor} [editorA] - The editor for the original view.
34+
* @property {import("../editor").Editor} [editorB] - The editor for the edited view.
35+
* @property {import("../edit_session").EditSession} [sessionA] - The edit session for the original view.
36+
* @property {import("../edit_session").EditSession} [sessionB] - The edit session for the edited view.
37+
* @property {string} [valueA] - The original content.
38+
* @property {string} [valueB] - The modified content.
39+
* @property {"a"|"b"} [inline] - Whether to show the original view("a") or modified view("b") for inline diff view
40+
* @property {IDiffProvider} [diffProvider] - Provider for computing differences between original and modified content.
41+
*/
42+
43+
/**
44+
* @typedef {Object} DiffViewOptions
45+
* @property {boolean} [showOtherLineNumbers=true] - Whether to show line numbers in the other editor's gutter
46+
* @property {boolean} [folding] - Whether to enable code folding widgets
47+
* @property {boolean} [syncSelections] - Whether to synchronize selections between both editors
48+
* @property {boolean} [ignoreTrimWhitespace] - Whether to ignore trimmed whitespace when computing diffs
49+
* @property {boolean} [wrap] - Whether to enable word wrapping in both editors
50+
* @property {number} [maxDiffs=5000] - Maximum number of diffs to compute before failing silently
51+
* @property {string|import("../../ace-internal").Ace.Theme} [theme] - Theme to apply to both editors
52+
*/
53+
54+
/**
55+
* @typedef {Object} IDiffProvider
56+
* @property {(originalLines: string[], modifiedLines: string[], opts?: any) => import("./diff/base_diff_view").DiffChunk[]} compute - Computes differences between original and modified lines
57+
*/
58+
59+
60+
/**
61+
* Creates a diff view for comparing code.
62+
* @param {DiffModel} [diffModel] model for the diff view
63+
* @param {DiffViewOptions} [options] options for the diff view
64+
* @returns {InlineDiffView|SplitDiffView} Configured diff view instance
65+
*/
66+
function createDiffView(diffModel, options) {
67+
diffModel = diffModel || {};
68+
diffModel.diffProvider = diffModel.diffProvider || new DiffProvider(); //use default diff provider;
69+
let diffView;
70+
if (diffModel.inline) {
71+
diffView = new InlineDiffView(diffModel);
72+
}
73+
else {
74+
diffView = new SplitDiffView(diffModel);
75+
}
76+
if (options) {
77+
diffView.setOptions(options);
78+
}
79+
80+
return diffView;
81+
}
82+
83+
exports.InlineDiffView = InlineDiffView;
84+
exports.SplitDiffView = SplitDiffView;
85+
exports.DiffProvider = DiffProvider;
86+
exports.createDiffView = createDiffView;

0 commit comments

Comments
 (0)