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 aa29e68

Browse files
committed
Merge branch 'master' into nunjucks-folding
2 parents 276bd31 + dd9fdf5 commit aa29e68

File tree

13 files changed

+1479
-825
lines changed

13 files changed

+1479
-825
lines changed

ace-internal.d.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export namespace Ace {
3232
type HoverTooltip = import("ace-code/src/tooltip").HoverTooltip;
3333
type Tooltip = import("ace-code/src/tooltip").Tooltip;
3434
type PopupManager = import("ace-code/src/tooltip").PopupManager;
35+
type TextInput = import("ace-code/src/keyboard/textinput").TextInput;
3536

3637
type AfterLoadCallback = (err: Error | null, module: unknown) => void;
3738
type LoaderFunction = (moduleName: string, afterLoad: AfterLoadCallback) => void;
@@ -967,12 +968,6 @@ export namespace Ace {
967968
new(session: EditSession): Selection;
968969
}
969970

970-
interface TextInput {
971-
resetSelection(): void;
972-
973-
setAriaOption(options?: { activeDescendant: string, role: string, setLabel: any }): void;
974-
}
975-
976971
type CompleterCallback = (error: any, completions: Completion[]) => void;
977972

978973
interface Completer {
@@ -1292,6 +1287,13 @@ export namespace Ace {
12921287
export interface ScrollbarEvents {
12931288
"scroll": (e: { data: number }) => void;
12941289
}
1290+
1291+
export interface TextInputAriaOptions {
1292+
activeDescendant?: string;
1293+
role?: string;
1294+
setLabel?: boolean;
1295+
inline?: boolean;
1296+
}
12951297
}
12961298

12971299

ace.d.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ declare module "ace-code" {
4141
type HoverTooltip = import("ace-code/src/tooltip").HoverTooltip;
4242
type Tooltip = import("ace-code/src/tooltip").Tooltip;
4343
type PopupManager = import("ace-code/src/tooltip").PopupManager;
44+
type TextInput = import("ace-code/src/keyboard/textinput").TextInput;
4445
type AfterLoadCallback = (err: Error | null, module: unknown) => void;
4546
type LoaderFunction = (moduleName: string, afterLoad: AfterLoadCallback) => void;
4647
export interface ConfigOptions {
@@ -775,14 +776,6 @@ declare module "ace-code" {
775776
var Selection: {
776777
new(session: EditSession): Selection;
777778
};
778-
interface TextInput {
779-
resetSelection(): void;
780-
setAriaOption(options?: {
781-
activeDescendant: string;
782-
role: string;
783-
setLabel: any;
784-
}): void;
785-
}
786779
type CompleterCallback = (error: any, completions: Completion[]) => void;
787780
interface Completer {
788781
identifierRegexps?: Array<RegExp>;
@@ -1032,6 +1025,12 @@ declare module "ace-code" {
10321025
data: number;
10331026
}) => void;
10341027
}
1028+
export interface TextInputAriaOptions {
1029+
activeDescendant?: string;
1030+
role?: string;
1031+
setLabel?: boolean;
1032+
inline?: boolean;
1033+
}
10351034
}
10361035
export const config: typeof import("ace-code/src/config");
10371036
export function edit(el?: string | (HTMLElement & {

src/editor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@ class Editor {
906906

907907
/**
908908
*
909-
* @param {string | string[]} command
909+
* @param {string | string[] | import("../ace-internal").Ace.Command} command
910910
* @param [args]
911911
* @return {boolean}
912912
*/

src/ext/diff/base_diff_view.js

Lines changed: 105 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ var Range = require("../../range").Range;
55
var dom = require("../../lib/dom");
66
var config = require("../../config");
77
var LineWidgets = require("../../line_widgets").LineWidgets;
8+
var ScrollDiffDecorator = require("./scroll_diff_decorator").ScrollDiffDecorator;
89

910
// @ts-ignore
1011
var css = require("./styles-css.js").cssText;
1112

1213
var Editor = require("../../editor").Editor;
1314
var Renderer = require("../../virtual_renderer").VirtualRenderer;
1415
var UndoManager = require("../../undomanager").UndoManager;
16+
var Decorator = require("../../layer/decorators").Decorator;
17+
1518
require("../../theme/textmate");
1619
// enable multiselect
1720
require("../../multi_select");
@@ -125,6 +128,8 @@ class BaseDiffView {
125128
diffModel.valueB || "")),
126129
chunks: []
127130
});
131+
132+
this.setupScrollbars();
128133
}
129134

130135
addGutterDecorators() {
@@ -141,7 +146,6 @@ class BaseDiffView {
141146
$setupModel(session, value) {
142147
var editor = new Editor(new Renderer(), session);
143148
editor.session.setUndoManager(new UndoManager());
144-
// editor.renderer.setOption("decoratorType", "diff");
145149
if (value) {
146150
editor.setValue(value, -1);
147151
}
@@ -290,13 +294,100 @@ class BaseDiffView {
290294
this.editorA && this.editorA.renderer.updateBackMarkers();
291295
this.editorB && this.editorB.renderer.updateBackMarkers();
292296

293-
//this.updateScrollBarDecorators();
297+
setTimeout(() => {
298+
this.updateScrollBarDecorators();
299+
}, 0);
294300

295301
if (this.$foldUnchangedOnInput) {
296302
this.foldUnchanged();
297303
}
298304
}
299305

306+
setupScrollbars() {
307+
/**
308+
* @param {Renderer & {$scrollDecorator: ScrollDiffDecorator}} renderer
309+
*/
310+
const setupScrollBar = (renderer) => {
311+
setTimeout(() => {
312+
this.$setScrollBarDecorators(renderer);
313+
this.updateScrollBarDecorators();
314+
}, 0);
315+
};
316+
317+
if (this.inlineDiffEditor) {
318+
setupScrollBar(this.activeEditor.renderer);
319+
}
320+
else {
321+
setupScrollBar(this.editorA.renderer);
322+
setupScrollBar(this.editorB.renderer);
323+
}
324+
325+
}
326+
327+
$setScrollBarDecorators(renderer) {
328+
if (renderer.$scrollDecorator) {
329+
renderer.$scrollDecorator.destroy();
330+
}
331+
renderer.$scrollDecorator = new ScrollDiffDecorator(renderer.scrollBarV, renderer, this.inlineDiffEditor);
332+
renderer.$scrollDecorator.setSessions(this.sessionA, this.sessionB);
333+
renderer.scrollBarV.setVisible(true);
334+
renderer.scrollBarV.element.style.bottom = renderer.scrollBarH.getHeight() + "px";
335+
}
336+
337+
$resetDecorators(renderer) {
338+
if (renderer.$scrollDecorator) {
339+
renderer.$scrollDecorator.destroy();
340+
}
341+
renderer.$scrollDecorator = new Decorator(renderer.scrollBarV, renderer);
342+
}
343+
344+
updateScrollBarDecorators() {
345+
if (this.inlineDiffEditor) {
346+
if (!this.activeEditor) {
347+
return;
348+
}
349+
this.activeEditor.renderer.$scrollDecorator.zones = [];
350+
}
351+
else {
352+
if (!this.editorA || !this.editorB) {
353+
return;
354+
}
355+
this.editorA.renderer.$scrollDecorator.zones = [];
356+
this.editorB.renderer.$scrollDecorator.zones = [];
357+
}
358+
359+
/**
360+
* @param {DiffChunk} change
361+
*/
362+
const updateDecorators = (editor, change) => {
363+
if (!editor) {
364+
return;
365+
}
366+
if (change.old.start.row != change.old.end.row) {
367+
editor.renderer.$scrollDecorator.addZone(change.old.start.row, change.old.end.row - 1, "delete");
368+
}
369+
if (change.new.start.row != change.new.end.row) {
370+
editor.renderer.$scrollDecorator.addZone(change.new.start.row, change.new.end.row - 1, "insert");
371+
}
372+
};
373+
374+
if (this.inlineDiffEditor) {
375+
this.chunks && this.chunks.forEach((lineChange) => {
376+
updateDecorators(this.activeEditor, lineChange);
377+
});
378+
this.activeEditor.renderer.$scrollDecorator.$updateDecorators(this.activeEditor.renderer.layerConfig);
379+
}
380+
else {
381+
this.chunks && this.chunks.forEach((lineChange) => {
382+
updateDecorators(this.editorA, lineChange);
383+
updateDecorators(this.editorB, lineChange);
384+
});
385+
386+
this.editorA.renderer.$scrollDecorator.$updateDecorators(this.editorA.renderer.layerConfig);
387+
this.editorB.renderer.$scrollDecorator.$updateDecorators(this.editorB.renderer.layerConfig);
388+
}
389+
}
390+
300391
/**
301392
*
302393
* @param {string[]} val1
@@ -366,7 +457,7 @@ class BaseDiffView {
366457
return row;
367458
}
368459

369-
/**
460+
/**
370461
* scroll locking
371462
* @abstract
372463
**/
@@ -468,8 +559,8 @@ class BaseDiffView {
468559
}
469560
}
470561
}
471-
472-
scheduleRealign() {
562+
563+
scheduleRealign() {
473564
if (!this.realignPending) {
474565
this.realignPending = true;
475566
this.editorA.renderer.on("beforeRender", this.realign);
@@ -500,6 +591,14 @@ class BaseDiffView {
500591
this.gutterDecoratorB && this.gutterDecoratorB.dispose();
501592
this.sessionA.selection.clearSelection();
502593
this.sessionB.selection.clearSelection();
594+
595+
if (this.savedOptionsA && this.savedOptionsA.customScrollbar) {
596+
this.$resetDecorators(this.editorA.renderer);
597+
}
598+
if (this.savedOptionsB &&this.savedOptionsB.customScrollbar) {
599+
this.$resetDecorators(this.editorB.renderer);
600+
}
601+
503602
this.editorA = this.editorB = null;
504603

505604
}
@@ -771,7 +870,7 @@ config.defineOptions(BaseDiffView.prototype, "DiffView", {
771870
return this.editorA.getTheme();
772871
}
773872
},
774-
});
873+
});
775874

776875
var emptyGutterRenderer = {
777876
getText: function name(params) {

src/ext/diff/diff_test.js

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ var {DiffProvider} = require("./providers/default");
1010
var ace = require("../../ace");
1111
var Range = require("../../range").Range;
1212
var editorA, editorB, diffView;
13+
const {Decorator} = require("../../layer/decorators");
14+
const {ScrollDiffDecorator} = require("./scroll_diff_decorator");
15+
1316

1417
var DEBUG = false;
1518

@@ -28,14 +31,14 @@ function setEditorPosition(editor) {
2831

2932
function getValueA(lines) {
3033
return lines.map(function(v) {
31-
return v[0];
34+
return v[0];
3235
}).filter(function(x) {
3336
return x != null;
3437
}).join("\n");
3538
}
3639
function getValueB(lines) {
3740
return lines.map(function(v) {
38-
return v.length == 2 ? v[1] : v[0];
41+
return v.length == 2 ? v[1] : v[0];
3942
}).filter(function(x) {
4043
return x != null;
4144
}).join("\n");
@@ -191,7 +194,7 @@ module.exports = {
191194

192195
diffView.setTheme("ace/theme/cloud_editor");
193196
assert.equal(diffView.editorA.getTheme(), "ace/theme/cloud_editor");
194-
assert.equal(diffView.editorB.getTheme(), "ace/theme/cloud_editor");
197+
assert.equal(diffView.editorB.getTheme(), "ace/theme/cloud_editor");
195198

196199
diffView.editorB.setTheme("ace/theme/textmate");
197200
assert.equal(diffView.editorA.getTheme(), "ace/theme/textmate");
@@ -212,7 +215,7 @@ module.exports = {
212215

213216
diffView.detach();
214217
checkEventRegistry();
215-
218+
216219
},
217220
"test: diff at ends": function() {
218221
var diffProvider = new DiffProvider();
@@ -353,6 +356,7 @@ module.exports = {
353356

354357
editorA.session.setValue(getValueA(simpleDiff));
355358
editorB.session.setValue(getValueB(simpleDiff));
359+
editorA.setOption("customScrollbar", true);
356360

357361
diffView = new InlineDiffView({
358362
editorA, editorB,
@@ -378,6 +382,8 @@ module.exports = {
378382

379383
assert.ok(!!diffView.editorB.renderer.$gutterLayer.$renderer);
380384

385+
assert.ok(editorA.renderer.$scrollDecorator instanceof ScrollDiffDecorator);
386+
381387
diffView.detach();
382388

383389
assert.equal(editorA.getOption("wrap"), "free");
@@ -388,9 +394,75 @@ module.exports = {
388394
assert.equal(editorB.getOption("fadeFoldWidgets"), false);
389395
assert.equal(editorB.getOption("showFoldWidgets"), true);
390396
assert.ok(!editorB.renderer.$gutterLayer.$renderer);
397+
398+
assert.ok(editorA.renderer.$scrollDecorator instanceof Decorator);
391399
},
400+
"test split diff scroll decorators": function(done) {
401+
editorA.session.setValue(["a", "b", "c"].join("\n"));
402+
editorB.session.setValue(["a", "c", "X"].join("\n"));
403+
404+
diffView = new DiffView({ editorA, editorB });
405+
diffView.setProvider(new DiffProvider());
406+
diffView.onInput();
407+
408+
409+
editorA.renderer.$loop._flush();
410+
editorB.renderer.$loop._flush();
411+
412+
setTimeout(() => {
413+
assertDecoratorsPlacement(editorA, false);
414+
done();
415+
}, 0);
416+
},
417+
"test inline diff scroll decorators": function(done) {
418+
editorA.session.setValue(["a", "b", "c"].join("\n"));
419+
editorB.session.setValue(["a", "c", "X"].join("\n"));
420+
421+
diffView = new InlineDiffView({ editorA, editorB, showSideA: true });
422+
diffView.setProvider(new DiffProvider());
423+
diffView.onInput();
424+
425+
editorA.renderer.$loop._flush();
426+
427+
setTimeout(() => {
428+
assertDecoratorsPlacement(editorA, true);
429+
done();
430+
}, 0);
431+
}
392432
};
393433

434+
function findPointFillStyle(imageData, y) {
435+
const data = imageData.slice(4 * y, 4 * (y + 1));
436+
const a = Math.round(data[3] / 256 * 100);
437+
if (a === 100) return "rgb(" + data.slice(0, 3).join(",") + ")";
438+
return "rgba(" + data.slice(0, 3).join(",") + "," + (a / 100) + ")";
439+
}
440+
441+
function assertDecoratorsPlacement(editor, inlineDiff) {
442+
const decoA = editor.renderer.$scrollDecorator;
443+
const ctxA = decoA.canvas.getContext("2d");
444+
const delRow = 1;
445+
const offA = decoA.sessionA.documentToScreenRow(delRow, 0) * decoA.lineHeight;
446+
const centerA = offA + decoA.lineHeight / 2;
447+
const yA = Math.round(decoA.heightRatio * centerA);
448+
let imgA = ctxA.getImageData(decoA.oneZoneWidth, 0, 1, decoA.canvasHeight).data;
449+
assert.equal(findPointFillStyle(imgA, yA), decoA.colors.light.delete);
450+
451+
if (inlineDiff) {
452+
//make sure that in inline diff, markers fills the whole line (except error decorators part)
453+
imgA = ctxA.getImageData(decoA.canvasWidth - 1, 0, 1, decoA.canvasHeight).data;
454+
assert.equal(findPointFillStyle(imgA, yA), decoA.colors.light.delete);
455+
}
456+
457+
const xB = decoA.oneZoneWidth * 2;
458+
const imgB = ctxA.getImageData(xB, 0, 1, decoA.canvasHeight).data;
459+
460+
const insRow = 2;
461+
const offB = decoA.sessionB.documentToScreenRow(insRow, 0) * decoA.lineHeight;
462+
const centerB = offB + decoA.lineHeight / 2;
463+
const yB = Math.round(decoA.heightRatio * centerB);
464+
assert.equal(findPointFillStyle(imgB, yB), decoA.colors.light.insert);
465+
}
394466

395467
if (typeof module !== "undefined" && module === require.main) {
396468
require("asyncjs").test.testcase(module.exports).exec();

0 commit comments

Comments
 (0)