Skip to content

Commit 58cec40

Browse files
committed
Changeset: Turn builder() into a real class
1 parent 9fc72c5 commit 58cec40

File tree

8 files changed

+99
-97
lines changed

8 files changed

+99
-97
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
`textLinesMutator()`, `toBaseTen()`, `toSplices()`.
5757
* `appendATextToAssembler()`: Deprecated in favor of the new
5858
`opsFromAText()` generator function.
59+
* `builder()`: Deprecated in favor of the new `Builder` class.
5960
* `newOp()`: Deprecated in favor of the new `Op` class.
6061

6162
### Notable enhancements

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
@@ -785,7 +785,7 @@ const _correctMarkersInPad = (atext, apool) => {
785785
// create changeset that removes these bad markers
786786
offset = 0;
787787

788-
const builder = Changeset.builder(text.length);
788+
const builder = new Changeset.Builder(text.length);
789789

790790
badMarkers.forEach((pos) => {
791791
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
@@ -81,7 +81,7 @@ exports.setPadHTML = async (pad, html) => {
8181
};
8282

8383
// create a new changeset with a helper builder object
84-
const builder = Changeset.builder(1);
84+
const builder = new Changeset.Builder(1);
8585

8686
// assemble each line into the builder
8787
eachAttribRun(newAttribs, (start, end, attribs) => {

src/node/utils/padDiff.js

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

7474
// build clearAuthorship changeset
75-
const builder = Changeset.builder(atext.text.length);
75+
const builder = new Changeset.Builder(atext.text.length);
7676
builder.keepText(atext.text, [['author', '']], this._pad.pool);
7777
const changeset = builder.toString();
7878

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

267267
const unpacked = Changeset.unpack(cs);
268-
const builder = Changeset.builder(unpacked.newLen);
268+
const builder = new Changeset.Builder(unpacked.newLen);
269269

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

src/static/js/AttributeManager.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
123123
* @param attribs an array of attributes
124124
*/
125125
_setAttributesOnRangeByLine(row, startCol, endCol, attribs) {
126-
const builder = Changeset.builder(this.rep.lines.totalWidth());
126+
const builder = new Changeset.Builder(this.rep.lines.totalWidth());
127127
ChangesetUtils.buildKeepToStartOfRange(this.rep, builder, [row, startCol]);
128128
ChangesetUtils.buildKeepRange(
129129
this.rep, builder, [row, startCol], [row, endCol], attribs, this.rep.apool);
@@ -307,7 +307,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
307307
*/
308308
setAttributeOnLine(lineNum, attributeName, attributeValue) {
309309
let loc = [0, 0];
310-
const builder = Changeset.builder(this.rep.lines.totalWidth());
310+
const builder = new Changeset.Builder(this.rep.lines.totalWidth());
311311
const hasMarker = this.lineHasMarker(lineNum);
312312

313313
ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 0]));
@@ -336,7 +336,7 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
336336
* @param attributeValue if given only attributes with equal value will be removed
337337
*/
338338
removeAttributeOnLine(lineNum, attributeName, attributeValue) {
339-
const builder = Changeset.builder(this.rep.lines.totalWidth());
339+
const builder = new Changeset.Builder(this.rep.lines.totalWidth());
340340
const hasMarker = this.lineHasMarker(lineNum);
341341
let found = false;
342342

src/static/js/Changeset.js

Lines changed: 86 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,97 +1941,98 @@ exports.attribsAttributeValue = (attribs, key, pool) => {
19411941

19421942
/**
19431943
* Incrementally builds a Changeset.
1944-
*
1945-
* @typedef {object} Builder
1946-
* @property {Function} insert -
1947-
* @property {Function} keep -
1948-
* @property {Function} keepText -
1949-
* @property {Function} remove -
1950-
* @property {Function} toString -
19511944
*/
1945+
class Builder {
1946+
/**
1947+
* @param {number} oldLen - Old length
1948+
*/
1949+
constructor(oldLen) {
1950+
this._oldLen = oldLen;
1951+
this._ops = [];
1952+
this._charBank = exports.stringAssembler();
1953+
}
19521954

1953-
/**
1954-
* @param {number} oldLen - Old length
1955-
* @returns {Builder}
1956-
*/
1957-
exports.builder = (oldLen) => {
1958-
const ops = [];
1959-
const charBank = exports.stringAssembler();
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 = (attribs && exports.makeAttribsString('=', attribs, pool)) || '';
1968+
o.chars = N;
1969+
o.lines = (L || 0);
1970+
this._ops.push(o);
1971+
return this;
1972+
}
19601973

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

1981-
/**
1982-
* @param {string} text - Text to keep.
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-
keepText: (text, attribs, pool) => {
1990-
ops.push(...opsFromText('=', text, attribs, pool));
1991-
return self;
1992-
},
1987+
/**
1988+
* @param {string} text - Text to insert.
1989+
* @param {(string|Attribute[])} attribs - Either [[key1,value1],[key2,value2],...] or '*0*1...'
1990+
* (no pool needed in latter case).
1991+
* @param {?AttributePool} pool - Attribute pool, only required if `attribs` is a list of
1992+
* attribute key, value pairs.
1993+
* @returns {Builder} this
1994+
*/
1995+
insert(text, attribs, pool) {
1996+
this._ops.push(...opsFromText('+', text, attribs, pool));
1997+
this._charBank.append(text);
1998+
return this;
1999+
}
19932000

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

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

2034-
return self;
2028+
/**
2029+
* @deprecated Use the `Builder` class instead.
2030+
* @param {number} oldLen - Old length
2031+
* @returns {Builder}
2032+
*/
2033+
exports.builder = (oldLen) => {
2034+
warnDeprecated('Changeset.builder() is deprecated; use the Changeset.Builder class instead');
2035+
return new Builder(oldLen);
20352036
};
20362037

20372038
exports.makeAttribsString = (opcode, attribs, pool) => {
@@ -2128,7 +2129,7 @@ exports.inverse = (cs, lines, alines, pool) => {
21282129
let curLineNextOp = new Op('+');
21292130

21302131
const unpacked = exports.unpack(cs);
2131-
const builder = exports.builder(unpacked.newLen);
2132+
const builder = new Builder(unpacked.newLen);
21322133

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

src/static/js/ace2_inner.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ function Ace2Inner(editorInfo, cssManagers) {
169169
// CCCCCCCCCCCCCCCCCCCC\n
170170
// CCCC\n
171171
// end[0]: <CCC end[1] CCC>-------\n
172-
const builder = Changeset.builder(rep.lines.totalWidth());
172+
const builder = new Changeset.Builder(rep.lines.totalWidth());
173173
ChangesetUtils.buildKeepToStartOfRange(rep, builder, start);
174174
ChangesetUtils.buildRemoveRange(rep, builder, start, end);
175175
builder.insert(newText, [
@@ -1271,7 +1271,7 @@ function Ace2Inner(editorInfo, cssManagers) {
12711271
if (shouldIndent && /[[(:{]\s*$/.exec(prevLineText)) {
12721272
theIndent += THE_TAB;
12731273
}
1274-
const cs = Changeset.builder(rep.lines.totalWidth()).keep(
1274+
const cs = new Changeset.Builder(rep.lines.totalWidth()).keep(
12751275
rep.lines.offsetOfIndex(lineNum), lineNum).insert(
12761276
theIndent, [
12771277
['author', thisAuthor],
@@ -1749,7 +1749,7 @@ function Ace2Inner(editorInfo, cssManagers) {
17491749
const spliceStartLineStart = rep.lines.offsetOfIndex(spliceStartLine);
17501750

17511751
const startBuilder = () => {
1752-
const builder = Changeset.builder(oldLen);
1752+
const builder = new Changeset.Builder(oldLen);
17531753
builder.keep(spliceStartLineStart, spliceStartLine);
17541754
builder.keep(spliceStart - spliceStartLineStart);
17551755
return builder;
@@ -2307,7 +2307,7 @@ function Ace2Inner(editorInfo, cssManagers) {
23072307

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

0 commit comments

Comments
 (0)