Skip to content

Commit b9e6fc8

Browse files
committed
Changeset: Turn builder() into a real class
1 parent e66e37b commit b9e6fc8

File tree

8 files changed

+101
-98
lines changed

8 files changed

+101
-98
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
generator function (combined with `serializeOps()`).
4444
* `appendATextToAssembler()`: Deprecated in favor of the new `opsFromAText()`
4545
generator function.
46+
* `builder()`: Deprecated in favor of the new `Builder` class.
4647
* `newOp()`: Deprecated in favor of the new `Op` class.
4748

4849
# 1.8.16

src/node/db/API.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ exports.restoreRevision = async (padID, rev) => {
538538
};
539539

540540
// create a new changeset with a helper builder object
541-
const builder = Changeset.builder(oldText.length);
541+
const builder = new Changeset.Builder(oldText.length);
542542

543543
// assemble each line into the builder
544544
eachAttribRun(atext.attribs, (start, end, attribs) => {

src/node/handler/PadMessageHandler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ const _correctMarkersInPad = (atext, apool) => {
759759
// create changeset that removes these bad markers
760760
offset = 0;
761761

762-
const builder = Changeset.builder(text.length);
762+
const builder = new Changeset.Builder(text.length);
763763

764764
badMarkers.forEach((pos) => {
765765
builder.keepText(text.substring(offset, pos));

src/node/utils/ImportHtml.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ exports.setPadHTML = async (pad, html) => {
6464
const newAttribs = `${result.lineAttribs.join('|1+1')}|1+1`;
6565

6666
// create a new changeset with a helper builder object
67-
const builder = Changeset.builder(1);
67+
const builder = new Changeset.Builder(1);
6868

6969
// assemble each line into the builder
7070
let textIndex = 0;

src/node/utils/padDiff.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ PadDiff.prototype._createClearAuthorship = async function (rev) {
6969
const atext = await this._pad.getInternalRevisionAText(rev);
7070

7171
// build clearAuthorship changeset
72-
const builder = Changeset.builder(atext.text.length);
72+
const builder = new Changeset.Builder(atext.text.length);
7373
builder.keepText(atext.text, [['author', '']], this._pad.pool);
7474
const changeset = builder.toString();
7575

@@ -262,7 +262,7 @@ PadDiff.prototype._createDeletionChangeset = function (cs, startAText, apool) {
262262
let curLineNextOp = new Changeset.Op('+');
263263

264264
const unpacked = Changeset.unpack(cs);
265-
const builder = Changeset.builder(unpacked.newLen);
265+
const builder = new Changeset.Builder(unpacked.newLen);
266266

267267
const consumeAttribRuns = (numChars, func /* (len, attribs, endsLine)*/) => {
268268
if (!curLineOps || curLineOpsLine !== curLine) {

src/static/js/AttributeManager.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
125125
* @param attribs an array of attributes
126126
*/
127127
_setAttributesOnRangeByLine(row, startCol, endCol, attribs) {
128-
const builder = Changeset.builder(this.rep.lines.totalWidth());
128+
const builder = new Changeset.Builder(this.rep.lines.totalWidth());
129129
ChangesetUtils.buildKeepToStartOfRange(this.rep, builder, [row, startCol]);
130130
ChangesetUtils.buildKeepRange(
131131
this.rep, builder, [row, startCol], [row, endCol], attribs, this.rep.apool);
@@ -285,7 +285,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
285285
*/
286286
setAttributeOnLine(lineNum, attributeName, attributeValue) {
287287
let loc = [0, 0];
288-
const builder = Changeset.builder(this.rep.lines.totalWidth());
288+
const builder = new Changeset.Builder(this.rep.lines.totalWidth());
289289
const hasMarker = this.lineHasMarker(lineNum);
290290

291291
ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 0]));
@@ -314,7 +314,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
314314
* @param attributeValue if given only attributes with equal value will be removed
315315
*/
316316
removeAttributeOnLine(lineNum, attributeName, attributeValue) {
317-
const builder = Changeset.builder(this.rep.lines.totalWidth());
317+
const builder = new Changeset.Builder(this.rep.lines.totalWidth());
318318
const hasMarker = this.lineHasMarker(lineNum);
319319
let found = false;
320320

src/static/js/Changeset.js

Lines changed: 88 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,98 +1915,100 @@ exports.attribsAttributeValue = (attribs, key, pool) => {
19151915

19161916
/**
19171917
* Incrementally builds a Changeset.
1918-
*
1919-
* @typedef {object} Builder
1920-
* @property {Function} insert -
1921-
* @property {Function} keep -
1922-
* @property {Function} keepText -
1923-
* @property {Function} remove -
1924-
* @property {Function} toString -
19251918
*/
1919+
class Builder {
1920+
/**
1921+
* @param {number} oldLen - Old length
1922+
*/
1923+
constructor(oldLen) {
1924+
this._oldLen = oldLen;
1925+
this._ops = [];
1926+
this._charBank = exports.stringAssembler();
1927+
}
19261928

1927-
/**
1928-
* @param {number} oldLen - Old length
1929-
* @returns {Builder}
1930-
*/
1931-
exports.builder = (oldLen) => {
1932-
const ops = [];
1933-
const charBank = exports.stringAssembler();
1929+
/**
1930+
* @param {number} N - Number of characters to keep.
1931+
* @param {number} L - Number of newlines among the `N` characters. If positive, the last
1932+
* character must be a newline.
1933+
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1934+
* (no pool needed in latter case).
1935+
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1936+
* attribute key, value pairs.
1937+
* @returns {Builder} this
1938+
*/
1939+
keep(N, L, attribs, pool) {
1940+
const o = new Op('=');
1941+
o.attribs = typeof attribs === 'string'
1942+
? attribs : new AttributeMap(pool).update(attribs || []).toString();
1943+
o.chars = N;
1944+
o.lines = (L || 0);
1945+
this._ops.push(o);
1946+
return this;
1947+
}
19341948

1935-
const self = {
1936-
/**
1937-
* @param {number} N - Number of characters to keep.
1938-
* @param {number} L - Number of newlines among the `N` characters. If positive, the last
1939-
* character must be a newline.
1940-
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1941-
* (no pool needed in latter case).
1942-
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1943-
* attribute key, value pairs.
1944-
* @returns {Builder} this
1945-
*/
1946-
keep: (N, L, attribs, pool) => {
1947-
const o = new Op('=');
1948-
o.attribs = typeof attribs === 'string'
1949-
? attribs : new AttributeMap(pool).update(attribs || []).toString();
1950-
o.chars = N;
1951-
o.lines = (L || 0);
1952-
ops.push(o);
1953-
return self;
1954-
},
1949+
/**
1950+
* @param {string} text - Text to keep.
1951+
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1952+
* (no pool needed in latter case).
1953+
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1954+
* attribute key, value pairs.
1955+
* @returns {Builder} this
1956+
*/
1957+
keepText(text, attribs, pool) {
1958+
this._ops.push(...opsFromText('=', text, attribs, pool));
1959+
return this;
1960+
}
19551961

1956-
/**
1957-
* @param {string} text - Text to keep.
1958-
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1959-
* (no pool needed in latter case).
1960-
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1961-
* attribute key, value pairs.
1962-
* @returns {Builder} this
1963-
*/
1964-
keepText: (text, attribs, pool) => {
1965-
ops.push(...opsFromText('=', text, attribs, pool));
1966-
return self;
1967-
},
1962+
/**
1963+
* @param {string} text - Text to insert.
1964+
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1965+
* (no pool needed in latter case).
1966+
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1967+
* attribute key, value pairs.
1968+
* @returns {Builder} this
1969+
*/
1970+
insert(text, attribs, pool) {
1971+
this._ops.push(...opsFromText('+', text, attribs, pool));
1972+
this._charBank.append(text);
1973+
return this;
1974+
}
19681975

1969-
/**
1970-
* @param {string} text - Text to insert.
1971-
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1972-
* (no pool needed in latter case).
1973-
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1974-
* attribute key, value pairs.
1975-
* @returns {Builder} this
1976-
*/
1977-
insert: (text, attribs, pool) => {
1978-
ops.push(...opsFromText('+', text, attribs, pool));
1979-
charBank.append(text);
1980-
return self;
1981-
},
1976+
/**
1977+
* @param {number} N - Number of characters to remove.
1978+
* @param {number} L - Number of newlines among the `N` characters. If positive, the last
1979+
* character must be a newline.
1980+
* @returns {Builder} this
1981+
*/
1982+
remove(N, L) {
1983+
const o = new Op('-');
1984+
o.attribs = '';
1985+
o.chars = N;
1986+
o.lines = (L || 0);
1987+
this._ops.push(o);
1988+
return this;
1989+
}
19821990

1983-
/**
1984-
* @param {number} N - Number of characters to remove.
1985-
* @param {number} L - Number of newlines among the `N` characters. If positive, the last
1986-
* character must be a newline.
1987-
* @returns {Builder} this
1988-
*/
1989-
remove: (N, L) => {
1990-
const o = new Op('-');
1991-
o.attribs = '';
1992-
o.chars = N;
1993-
o.lines = (L || 0);
1994-
ops.push(o);
1995-
return self;
1996-
},
1997-
1998-
toString: () => {
1999-
/** @type {number} */
2000-
let lengthChange;
2001-
const serializedOps = exports.serializeOps((function* () {
2002-
lengthChange = yield* exports.canonicalizeOps(ops, true);
2003-
})());
2004-
const newLen = oldLen + lengthChange;
2005-
return exports.pack(oldLen, newLen, serializedOps, charBank.toString());
2006-
},
2007-
};
1991+
toString() {
1992+
/** @type {number} */
1993+
let lengthChange;
1994+
const serializedOps = exports.serializeOps((function* () {
1995+
lengthChange = yield* exports.canonicalizeOps(this._ops, true);
1996+
}).call(this));
1997+
const newLen = this._oldLen + lengthChange;
1998+
return exports.pack(this._oldLen, newLen, serializedOps, this._charBank.toString());
1999+
}
2000+
}
2001+
exports.Builder = Builder;
20082002

2009-
return self;
2003+
/**
2004+
* @deprecated Use the `Builder` class instead.
2005+
* @param {number} oldLen - Old length
2006+
* @returns {Builder}
2007+
*/
2008+
exports.builder = (oldLen) => {
2009+
padutils.warnDeprecated(
2010+
'Changeset.builder() is deprecated; use the Changeset.Builder class instead');
2011+
return new Builder(oldLen);
20102012
};
20112013

20122014
/**
@@ -2107,7 +2109,7 @@ exports.inverse = (cs, lines, alines, pool) => {
21072109
let curLineNextOp = new Op('+');
21082110

21092111
const unpacked = exports.unpack(cs);
2110-
const builder = exports.builder(unpacked.newLen);
2112+
const builder = new Builder(unpacked.newLen);
21112113

21122114
const consumeAttribRuns = (numChars, func /* (len, attribs, endsLine)*/) => {
21132115
if (!curLineOps || curLineOpsLine !== curLine) {

src/static/js/ace2_inner.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ function Ace2Inner(editorInfo, cssManagers) {
170170
// CCCCCCCCCCCCCCCCCCCC\n
171171
// CCCC\n
172172
// end[0]: <CCC end[1] CCC>-------\n
173-
const builder = Changeset.builder(rep.lines.totalWidth());
173+
const builder = new Changeset.Builder(rep.lines.totalWidth());
174174
ChangesetUtils.buildKeepToStartOfRange(rep, builder, start);
175175
ChangesetUtils.buildRemoveRange(rep, builder, start, end);
176176
builder.insert(newText, [
@@ -1272,7 +1272,7 @@ function Ace2Inner(editorInfo, cssManagers) {
12721272
if (shouldIndent && /[[(:{]\s*$/.exec(prevLineText)) {
12731273
theIndent += THE_TAB;
12741274
}
1275-
const cs = Changeset.builder(rep.lines.totalWidth()).keep(
1275+
const cs = new Changeset.Builder(rep.lines.totalWidth()).keep(
12761276
rep.lines.offsetOfIndex(lineNum), lineNum).insert(
12771277
theIndent, [
12781278
['author', thisAuthor],
@@ -1746,7 +1746,7 @@ function Ace2Inner(editorInfo, cssManagers) {
17461746
const spliceStartLineStart = rep.lines.offsetOfIndex(spliceStartLine);
17471747

17481748
const startBuilder = () => {
1749-
const builder = Changeset.builder(oldLen);
1749+
const builder = new Changeset.Builder(oldLen);
17501750
builder.keep(spliceStartLineStart, spliceStartLine);
17511751
builder.keep(spliceStart - spliceStartLineStart);
17521752
return builder;
@@ -2297,7 +2297,7 @@ function Ace2Inner(editorInfo, cssManagers) {
22972297

22982298
// 3-renumber every list item of the same level from the beginning, level 1
22992299
// IMPORTANT: never skip a level because there imbrication may be arbitrary
2300-
const builder = Changeset.builder(rep.lines.totalWidth());
2300+
const builder = new Changeset.Builder(rep.lines.totalWidth());
23012301
let loc = [0, 0];
23022302
const applyNumberList = (line, level) => {
23032303
// init

0 commit comments

Comments
 (0)