Skip to content

Commit 441413a

Browse files
committed
Changeset: Turn builder() into a real class
1 parent 728ab26 commit 441413a

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
@@ -28,6 +28,7 @@
2828
generator function (combined with `serializeOps()`).
2929
* `appendATextToAssembler()`: Deprecated in favor of the new `opsFromAText()`
3030
generator function.
31+
* `builder()`: Deprecated in favor of the new `Builder` class.
3132
* `newOp()`: Deprecated in favor of the new `Op` class.
3233

3334
# 1.8.15

src/node/db/API.js

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

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

545545
// assemble each line into the builder
546546
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
@@ -1934,98 +1934,100 @@ exports.attribsAttributeValue = (attribs, key, pool) => {
19341934

19351935
/**
19361936
* Incrementally builds a Changeset.
1937-
*
1938-
* @typedef {object} Builder
1939-
* @property {Function} insert -
1940-
* @property {Function} keep -
1941-
* @property {Function} keepText -
1942-
* @property {Function} remove -
1943-
* @property {Function} toString -
19441937
*/
1938+
class Builder {
1939+
/**
1940+
* @param {number} oldLen - Old length
1941+
*/
1942+
constructor(oldLen) {
1943+
this._oldLen = oldLen;
1944+
this._ops = [];
1945+
this._charBank = exports.stringAssembler();
1946+
}
19451947

1946-
/**
1947-
* @param {number} oldLen - Old length
1948-
* @returns {Builder}
1949-
*/
1950-
exports.builder = (oldLen) => {
1951-
const ops = [];
1952-
const charBank = exports.stringAssembler();
1948+
/**
1949+
* @param {number} N - Number of characters to keep.
1950+
* @param {number} L - Number of newlines among the `N` characters. If positive, the last
1951+
* character must be a newline.
1952+
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1953+
* (no pool needed in latter case).
1954+
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1955+
* attribute key, value pairs.
1956+
* @returns {Builder} this
1957+
*/
1958+
keep(N, L, attribs, pool) {
1959+
const o = new Op('=');
1960+
o.attribs = typeof attribs === 'string'
1961+
? attribs : new AttributeMap(pool).update(attribs || []).toString();
1962+
o.chars = N;
1963+
o.lines = (L || 0);
1964+
this._ops.push(o);
1965+
return this;
1966+
}
19531967

1954-
const self = {
1955-
/**
1956-
* @param {number} N - Number of characters to keep.
1957-
* @param {number} L - Number of newlines among the `N` characters. If positive, the last
1958-
* character must be a newline.
1959-
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1960-
* (no pool needed in latter case).
1961-
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1962-
* attribute key, value pairs.
1963-
* @returns {Builder} this
1964-
*/
1965-
keep: (N, L, attribs, pool) => {
1966-
const o = new Op('=');
1967-
o.attribs = typeof attribs === 'string'
1968-
? attribs : new AttributeMap(pool).update(attribs || []).toString();
1969-
o.chars = N;
1970-
o.lines = (L || 0);
1971-
ops.push(o);
1972-
return self;
1973-
},
1968+
/**
1969+
* @param {string} text - Text to keep.
1970+
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1971+
* (no pool needed in latter case).
1972+
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1973+
* attribute key, value pairs.
1974+
* @returns {Builder} this
1975+
*/
1976+
keepText(text, attribs, pool) {
1977+
this._ops.push(...opsFromText('=', text, attribs, pool));
1978+
return this;
1979+
}
19741980

1975-
/**
1976-
* @param {string} text - Text to keep.
1977-
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1978-
* (no pool needed in latter case).
1979-
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1980-
* attribute key, value pairs.
1981-
* @returns {Builder} this
1982-
*/
1983-
keepText: (text, attribs, pool) => {
1984-
ops.push(...opsFromText('=', text, attribs, pool));
1985-
return self;
1986-
},
1981+
/**
1982+
* @param {string} text - Text to insert.
1983+
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1984+
* (no pool needed in latter case).
1985+
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1986+
* attribute key, value pairs.
1987+
* @returns {Builder} this
1988+
*/
1989+
insert(text, attribs, pool) {
1990+
this._ops.push(...opsFromText('+', text, attribs, pool));
1991+
this._charBank.append(text);
1992+
return this;
1993+
}
19871994

1988-
/**
1989-
* @param {string} text - Text to insert.
1990-
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1991-
* (no pool needed in latter case).
1992-
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1993-
* attribute key, value pairs.
1994-
* @returns {Builder} this
1995-
*/
1996-
insert: (text, attribs, pool) => {
1997-
ops.push(...opsFromText('+', text, attribs, pool));
1998-
charBank.append(text);
1999-
return self;
2000-
},
1995+
/**
1996+
* @param {number} N - Number of characters to remove.
1997+
* @param {number} L - Number of newlines among the `N` characters. If positive, the last
1998+
* character must be a newline.
1999+
* @returns {Builder} this
2000+
*/
2001+
remove(N, L) {
2002+
const o = new Op('-');
2003+
o.attribs = '';
2004+
o.chars = N;
2005+
o.lines = (L || 0);
2006+
this._ops.push(o);
2007+
return this;
2008+
}
20012009

2002-
/**
2003-
* @param {number} N - Number of characters to remove.
2004-
* @param {number} L - Number of newlines among the `N` characters. If positive, the last
2005-
* character must be a newline.
2006-
* @returns {Builder} this
2007-
*/
2008-
remove: (N, L) => {
2009-
const o = new Op('-');
2010-
o.attribs = '';
2011-
o.chars = N;
2012-
o.lines = (L || 0);
2013-
ops.push(o);
2014-
return self;
2015-
},
2016-
2017-
toString: () => {
2018-
/** @type {number} */
2019-
let lengthChange;
2020-
const serializedOps = exports.serializeOps((function* () {
2021-
lengthChange = yield* exports.canonicalizeOps(ops, true);
2022-
})());
2023-
const newLen = oldLen + lengthChange;
2024-
return exports.pack(oldLen, newLen, serializedOps, charBank.toString());
2025-
},
2026-
};
2010+
toString() {
2011+
/** @type {number} */
2012+
let lengthChange;
2013+
const serializedOps = exports.serializeOps((function* () {
2014+
lengthChange = yield* exports.canonicalizeOps(this._ops, true);
2015+
}).call(this));
2016+
const newLen = this._oldLen + lengthChange;
2017+
return exports.pack(this._oldLen, newLen, serializedOps, this._charBank.toString());
2018+
}
2019+
}
2020+
exports.Builder = Builder;
20272021

2028-
return self;
2022+
/**
2023+
* @deprecated Use the `Builder` class instead.
2024+
* @param {number} oldLen - Old length
2025+
* @returns {Builder}
2026+
*/
2027+
exports.builder = (oldLen) => {
2028+
padutils.warnWithStack(
2029+
'Changeset.builder() is deprecated; use the Changeset.Builder class instead');
2030+
return new Builder(oldLen);
20292031
};
20302032

20312033
/**
@@ -2126,7 +2128,7 @@ exports.inverse = (cs, lines, alines, pool) => {
21262128
let curLineNextOp = new Op('+');
21272129

21282130
const unpacked = exports.unpack(cs);
2129-
const builder = exports.builder(unpacked.newLen);
2131+
const builder = new Builder(unpacked.newLen);
21302132

21312133
const consumeAttribRuns = (numChars, func /* (len, attribs, endsLine)*/) => {
21322134
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)