Skip to content

Commit 951ef83

Browse files
committed
Changeset: Turn builder() into a real class
1 parent d3f313a commit 951ef83

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
@@ -30,6 +30,7 @@
3030
generator function (combined with `serializeOps()`).
3131
* `appendATextToAssembler()`: Deprecated in favor of the new `opsFromAText()`
3232
generator function.
33+
* `builder()`: Deprecated in favor of the new `Builder` class.
3334
* `newOp()`: Deprecated in favor of the new `Op` class.
3435

3536
# 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
@@ -1918,98 +1918,100 @@ exports.attribsAttributeValue = (attribs, key, pool) => {
19181918

19191919
/**
19201920
* Incrementally builds a Changeset.
1921-
*
1922-
* @typedef {object} Builder
1923-
* @property {Function} insert -
1924-
* @property {Function} keep -
1925-
* @property {Function} keepText -
1926-
* @property {Function} remove -
1927-
* @property {Function} toString -
19281921
*/
1922+
class Builder {
1923+
/**
1924+
* @param {number} oldLen - Old length
1925+
*/
1926+
constructor(oldLen) {
1927+
this._oldLen = oldLen;
1928+
this._ops = [];
1929+
this._charBank = exports.stringAssembler();
1930+
}
19291931

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

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

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

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

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

2012-
return self;
2006+
/**
2007+
* @deprecated Use the `Builder` class instead.
2008+
* @param {number} oldLen - Old length
2009+
* @returns {Builder}
2010+
*/
2011+
exports.builder = (oldLen) => {
2012+
padutils.warnWithStack(
2013+
'Changeset.builder() is deprecated; use the Changeset.Builder class instead');
2014+
return new Builder(oldLen);
20132015
};
20142016

20152017
/**
@@ -2110,7 +2112,7 @@ exports.inverse = (cs, lines, alines, pool) => {
21102112
let curLineNextOp = new Op('+');
21112113

21122114
const unpacked = exports.unpack(cs);
2113-
const builder = exports.builder(unpacked.newLen);
2115+
const builder = new Builder(unpacked.newLen);
21142116

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