From 83c0e624b3e3283763d51e6233652451d3cc4229 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Mon, 29 Nov 2021 21:42:07 -0500 Subject: [PATCH 001/192] add typescript dependency --- package-lock.json | 6 ++++++ package.json | 1 + 2 files changed, 7 insertions(+) diff --git a/package-lock.json b/package-lock.json index 489f69df9..cf7f4ea3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -826,6 +826,12 @@ "dev": true, "optional": true }, + "typescript": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "dev": true + }, "uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", diff --git a/package.json b/package.json index 475a7c727..7b3e2fe5b 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "less": ">=1.5.1 <3.0.0", "mocha": ">=2.4.1", "pjs": ">=3.1.0 <5.0.0", + "typescript": "^4.5.2", "uglify-js": "2.x" } } From 3b5b1f8f48f3acbea467c78cc5bcd5c4377981c5 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 09:27:02 -0500 Subject: [PATCH 002/192] convert Point to ES6 class --- src/commands/math/commands.js | 4 ++-- src/commands/text.js | 2 +- src/tree.js | 18 ++++++++++-------- test/unit/select.test.js | 28 ++++++++++++++-------------- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 3a5214ac8..ddcac220e 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -248,11 +248,11 @@ var SupSub = P(MathCommand, function(_, super_) { else if (!src.isEmpty()) { // ins src children at -dir end of dest src.jQ.children().insAtDirEnd(-dir, dest.jQ); var children = src.children().disown(); - var pt = Point(dest, children.ends[R], dest.ends[L]); + var pt = new Point(dest, children.ends[R], dest.ends[L]); if (dir === L) children.adopt(dest, dest.ends[R], 0); else children.adopt(dest, 0, dest.ends[L]); } - else var pt = Point(dest, 0, dest.ends[L]); + else var pt = new Point(dest, 0, dest.ends[L]); this.placeCursor = (function(dest, src) { // TODO: don't monkey-patch return function(cursor) { cursor.insAtDirEnd(-dir, dest || src); }; }(dest, src)); diff --git a/src/commands/text.js b/src/commands/text.js index fdaaf5da0..12d144a2e 100644 --- a/src/commands/text.js +++ b/src/commands/text.js @@ -185,7 +185,7 @@ var TextBlock = P(Node, function(_, super_) { else { var newTextPc = cursor[R].splitRight(this.anticursorPosition - cursorPosition); } - cursor.anticursor = Point(this, newTextPc[L], newTextPc); + cursor.anticursor = new Point(this, newTextPc[L], newTextPc); } } }; diff --git a/src/tree.js b/src/tree.js index 5eb463493..3a08ba300 100644 --- a/src/tree.js +++ b/src/tree.js @@ -58,21 +58,23 @@ var $ = P(jQuery, function(_) { }; }); -var Point = P(function(_) { - _.parent = 0; - _[L] = 0; - _[R] = 0; +class Point { - _.init = function(parent, leftward, rightward) { + // keeping init around only for tests + init (parent, leftward, rightward) { this.parent = parent; this[L] = leftward; this[R] = rightward; + } + + constructor (parent, leftward, rightward) { + this.init(parent, leftward, rightward); }; - this.copy = function(pt) { - return Point(pt.parent, pt[L], pt[R]); + static copy (pt) { + return new Point(pt.parent, pt[L], pt[R]); }; -}); +} /* Mathquill used to create a global dictionary that held onto diff --git a/test/unit/select.test.js b/test/unit/select.test.js index 61707d8f0..9b5a45802 100644 --- a/test/unit/select.test.js +++ b/test/unit/select.test.js @@ -15,9 +15,9 @@ suite('Cursor::select()', function() { return Node.p.selectChildren.apply(this, arguments); }; - Point.p.init.call(cursor, A.parent, A[L], A[R]); + Point.prototype.init.call(cursor, A.parent, A[L], A[R]); cursor.startSelection(); - Point.p.init.call(cursor, B.parent, B[L], B[R]); + Point.prototype.init.call(cursor, B.parent, B[L], B[R]); assert.equal(cursor.select(), true); assert.equal(count, 1); @@ -29,13 +29,13 @@ suite('Cursor::select()', function() { var child1 = Node().adopt(parent, parent.ends[R], 0); var child2 = Node().adopt(parent, parent.ends[R], 0); var child3 = Node().adopt(parent, parent.ends[R], 0); - var A = Point(parent, 0, child1); - var B = Point(parent, child1, child2); - var C = Point(parent, child2, child3); - var D = Point(parent, child3, 0); - var pt1 = Point(child1, 0, 0); - var pt2 = Point(child2, 0, 0); - var pt3 = Point(child3, 0, 0); + var A = new Point(parent, 0, child1); + var B = new Point(parent, child1, child2); + var C = new Point(parent, child2, child3); + var D = new Point(parent, child3, 0); + var pt1 = new Point(child1, 0, 0); + var pt2 = new Point(child2, 0, 0); + var pt3 = new Point(child3, 0, 0); test('same parent, one Node', function() { assertSelection(A, B, child1); @@ -75,7 +75,7 @@ suite('Cursor::select()', function() { }); test('same Point', function() { - Point.p.init.call(cursor, A.parent, A[L], A[R]); + Point.prototype.init.call(cursor, A.parent, A[L], A[R]); cursor.startSelection(); assert.equal(cursor.select(), false); }); @@ -83,14 +83,14 @@ suite('Cursor::select()', function() { test('different trees', function() { var anotherTree = Node(); - Point.p.init.call(cursor, A.parent, A[L], A[R]); + Point.prototype.init.call(cursor, A.parent, A[L], A[R]); cursor.startSelection(); - Point.p.init.call(cursor, anotherTree, 0, 0); + Point.prototype.init.call(cursor, anotherTree, 0, 0); assert.throws(function() { cursor.select(); }); - Point.p.init.call(cursor, anotherTree, 0, 0); + Point.prototype.init.call(cursor, anotherTree, 0, 0); cursor.startSelection(); - Point.p.init.call(cursor, A.parent, A[L], A[R]); + Point.prototype.init.call(cursor, A.parent, A[L], A[R]); assert.throws(function() { cursor.select(); }); }); }); From 353bebd138afb81c1888192f3cce1ab05f9c64c9 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 10:56:09 -0500 Subject: [PATCH 003/192] convert Node to ES6 class --- src/services/keystroke.js | 21 ++++---- src/tree.js | 102 +++++++++++++++++++++----------------- test/unit/select.test.js | 12 ++--- test/unit/tree.test.js | 62 +++++++++++------------ 4 files changed, 104 insertions(+), 93 deletions(-) diff --git a/src/services/keystroke.js b/src/services/keystroke.js index fa59223b5..c10c9ad1d 100644 --- a/src/services/keystroke.js +++ b/src/services/keystroke.js @@ -9,8 +9,8 @@ Controller.open(function(_) { }; }); -Node.open(function(_) { - _.keystroke = function(key, e, ctrlr) { +class Node extends NodeBase { + keystroke (key, e, ctrlr) { var cursor = ctrlr.cursor; switch (key) { @@ -189,15 +189,14 @@ Node.open(function(_) { ctrlr.scrollHoriz(); }; - _.moveOutOf = // called by Controller::escapeDir, moveDir - _.moveTowards = // called by Controller::moveDir - _.deleteOutOf = // called by Controller::deleteDir - _.deleteTowards = // called by Controller::deleteDir - _.unselectInto = // called by Controller::selectDir - _.selectOutOf = // called by Controller::selectDir - _.selectTowards = // called by Controller::selectDir - function() { pray('overridden or never called on this node'); }; -}); + moveOutOf () { pray('overridden or never called on this node'); } // called by Controller::escapeDir, moveDir + moveTowards () { pray('overridden or never called on this node'); } // called by Controller::moveDir + deleteOutOf () { pray('overridden or never called on this node'); } // called by Controller::deleteDir + deleteTowards () { pray('overridden or never called on this node'); } // called by Controller::deleteDir + unselectInto () { pray('overridden or never called on this node'); } // called by Controller::selectDir + selectOutOf () { pray('overridden or never called on this node'); } // called by Controller::selectDir + selectTowards () { pray('overridden or never called on this node'); } // called by Controller::selectDir +} Controller.open(function(_) { this.onNotify(function(e) { diff --git a/src/tree.js b/src/tree.js index 3a08ba300..8ce9385e2 100644 --- a/src/tree.js +++ b/src/tree.js @@ -153,47 +153,59 @@ function foldNodes (ends, fold, yield_) { /** * MathQuill virtual-DOM tree-node abstract base class */ -var Node = P(function(_) { - _[L] = 0; - _[R] = 0 - _.parent = 0; +class NodeBase { + static idCounter = 0; + static uniqueNodeId() { return Node.idCounter += 1; } - var id = 0; - function uniqueNodeId() { return id += 1; } - - this.getNodeOfElement = function (el) { + static getNodeOfElement (el) { if (!el) return; if (!el.nodeType) throw new Error('must pass an HTMLElement to Node.getNodeOfElement') return el.mqBlockNode || el.mqCmdNode; } - this.linkElementByBlockId = function (elm, id) { + static linkElementByBlockId (elm, id) { Node.linkElementByBlockNode(elm, TempByIdDict[id]); }; - this.linkElementByBlockNode = function (elm, blockNode) { + static linkElementByBlockNode (elm, blockNode) { elm.mqBlockNode = blockNode; }; - this.linkElementByCmdNode = function (elm, cmdNode) { + static linkElementByCmdNode (elm, cmdNode) { elm.mqCmdNode = cmdNode; }; - _.init = function() { - this.id = uniqueNodeId(); - TempByIdDict[id] = this; - scheduleDictionaryCleaning(id, this); + // any extensions that define an init method can call + // this version instead of completely overwriting it + initBaseNode () { + this[L] = 0; + this[R] = 0 + this.parent = 0; + + this.id = Node.uniqueNodeId(); + this.jQ = $(); + + TempByIdDict[this.id] = this; + scheduleDictionaryCleaning(this.id, this); this.ends = {}; this.ends[L] = 0; this.ends[R] = 0; }; - _.toString = function() { return '{{ MathQuill Node #'+this.id+' }}'; }; + // PJS expects a init method + init () { + this.initBaseNode(); + } - _.jQ = $(); - _.jQadd = function(jQ) { return this.jQ = this.jQ.add(jQ); }; - _.jQize = function(jQ) { + constructor () { + this.init(); + } + + toString () { return '{{ MathQuill Node #'+this.id+' }}'; }; + + jQadd (jQ) { return this.jQ = this.jQ.add(jQ); }; + jQize (jQ) { // jQuery-ifies this.html() and links up the .jQ of all corresponding Nodes var jQ = $(jQ || this.html()); @@ -225,7 +237,7 @@ var Node = P(function(_) { return jQ; }; - _.createDir = function(dir, cursor) { + createDir (dir, cursor) { prayDirection(dir); var node = this; node.jQize(); @@ -233,13 +245,13 @@ var Node = P(function(_) { cursor[dir] = node.adopt(cursor.parent, cursor[L], cursor[R]); return node; }; - _.createLeftOf = function(el) { return this.createDir(L, el); }; + createLeftOf (el) { return this.createDir(L, el); }; - _.selectChildren = function(leftEnd, rightEnd) { + selectChildren (leftEnd, rightEnd) { return Selection(leftEnd, rightEnd); }; - _.bubble = function (yield_) { + bubble (yield_) { for (var ancestor = this; ancestor; ancestor = ancestor.parent) { var result = yield_(ancestor); if (result === false) break; @@ -248,7 +260,7 @@ var Node = P(function(_) { return this; }; - _.postOrder = function(yield_) { + postOrder (yield_) { (function recurse(descendant) { descendant.eachChild(recurse); yield_(descendant); @@ -257,64 +269,64 @@ var Node = P(function(_) { return this; }; - _.isEmpty = function() { + isEmpty () { return this.ends[L] === 0 && this.ends[R] === 0; }; - - _.isEmptyParens = function () { + + isEmptyParens () { if (!this.isEmpty()) return false; if (!this.parent) return false; return this.parent.ctrlSeq === '\\left('; } - _.isEmptySquareBrackets = function () { + isEmptySquareBrackets () { if (!this.isEmpty()) return false; if (!this.parent) return false; return this.parent.ctrlSeq === '\\left['; } - _.isStyleBlock = function() { + isStyleBlock () { return false; }; - _.isTextBlock = function() { + isTextBlock () { return false; }; - _.children = function() { + children () { return Fragment(this.ends[L], this.ends[R]); }; - _.eachChild = function(yield_) { + eachChild (yield_) { eachNode(this.ends, yield_); return this; }; - _.foldChildren = function (fold, yield_) { + foldChildren (fold, yield_) { return foldNodes(this.ends, fold, yield_); }; - _.withDirAdopt = function(dir, parent, withDir, oppDir) { + withDirAdopt (dir, parent, withDir, oppDir) { Fragment(this, this).withDirAdopt(dir, parent, withDir, oppDir); return this; }; - _.adopt = function(parent, leftward, rightward) { + adopt (parent, leftward, rightward) { Fragment(this, this).adopt(parent, leftward, rightward); return this; }; - _.disown = function() { + disown () { Fragment(this, this).disown(); return this; }; - _.remove = function() { + remove () { this.jQ.remove(); return this.disown(); }; - _.isParentSimpleSubscript = function () { + isParentSimpleSubscript () { if (!this.parent) return false; if (!(this.parent.parent instanceof SupSub)) return false; @@ -333,13 +345,13 @@ var Node = P(function(_) { }; // Overridden by child classes - _.finalizeTree = function () { }; - _.contactWeld = function () { }; - _.blur = function () { }; - _.intentionalBlur = function () { }; - _.reflow = function () { }; - _.registerInnerField = function () { }; -}); + finalizeTree () { }; + contactWeld () { }; + blur () { }; + intentionalBlur () { }; + reflow () { }; + registerInnerField () { }; +} function prayWellFormed(parent, leftward, rightward) { pray('a parent is always present', parent); diff --git a/test/unit/select.test.js b/test/unit/select.test.js index 9b5a45802..02e73c8a1 100644 --- a/test/unit/select.test.js +++ b/test/unit/select.test.js @@ -12,7 +12,7 @@ suite('Cursor::select()', function() { count += 1; assert.equal(frag.ends[L], leftEnd); assert.equal(frag.ends[R], rightEnd); - return Node.p.selectChildren.apply(this, arguments); + return Node.prototype.selectChildren.apply(this, arguments); }; Point.prototype.init.call(cursor, A.parent, A[L], A[R]); @@ -25,10 +25,10 @@ suite('Cursor::select()', function() { }(A, B)(B, A)); } - var parent = Node(); - var child1 = Node().adopt(parent, parent.ends[R], 0); - var child2 = Node().adopt(parent, parent.ends[R], 0); - var child3 = Node().adopt(parent, parent.ends[R], 0); + var parent = new Node(); + var child1 = new Node().adopt(parent, parent.ends[R], 0); + var child2 = new Node().adopt(parent, parent.ends[R], 0); + var child3 = new Node().adopt(parent, parent.ends[R], 0); var A = new Point(parent, 0, child1); var B = new Point(parent, child1, child2); var C = new Point(parent, child2, child3); @@ -81,7 +81,7 @@ suite('Cursor::select()', function() { }); test('different trees', function() { - var anotherTree = Node(); + var anotherTree = new Node(); Point.prototype.init.call(cursor, A.parent, A[L], A[R]); cursor.startSelection(); diff --git a/test/unit/tree.test.js b/test/unit/tree.test.js index a1cc5e3fa..5a30395e8 100644 --- a/test/unit/tree.test.js +++ b/test/unit/tree.test.js @@ -14,8 +14,8 @@ suite('tree', function() { } test('the empty case', function() { - var parent = Node(); - var child = Node(); + var parent = new Node(); + var child = new Node(); child.adopt(parent, 0, 0); @@ -28,9 +28,9 @@ suite('tree', function() { }); test('with two children from the left', function() { - var parent = Node(); - var one = Node(); - var two = Node(); + var parent = new Node(); + var one = new Node(); + var two = new Node(); one.adopt(parent, 0, 0); two.adopt(parent, one, 0); @@ -39,9 +39,9 @@ suite('tree', function() { }); test('with two children from the right', function() { - var parent = Node(); - var one = Node(); - var two = Node(); + var parent = new Node(); + var one = new Node(); + var two = new Node(); two.adopt(parent, 0, 0); one.adopt(parent, 0, two); @@ -50,10 +50,10 @@ suite('tree', function() { }); test('adding one in the middle', function() { - var parent = Node(); - var leftward = Node(); - var rightward = Node(); - var middle = Node(); + var parent = new Node(); + var leftward = new Node(); + var rightward = new Node(); + var middle = new Node(); leftward.adopt(parent, 0, 0); rightward.adopt(parent, leftward, 0); @@ -80,8 +80,8 @@ suite('tree', function() { } test('the empty case', function() { - var parent = Node(); - var child = Node(); + var parent = new Node(); + var child = new Node(); child.adopt(parent, 0, 0); child.disown(); @@ -91,9 +91,9 @@ suite('tree', function() { }); test('disowning the right end child', function() { - var parent = Node(); - var one = Node(); - var two = Node(); + var parent = new Node(); + var one = new Node(); + var two = new Node(); one.adopt(parent, 0, 0); two.adopt(parent, one, 0); @@ -110,9 +110,9 @@ suite('tree', function() { }); test('disowning the left end child', function() { - var parent = Node(); - var one = Node(); - var two = Node(); + var parent = new Node(); + var one = new Node(); + var two = new Node(); one.adopt(parent, 0, 0); two.adopt(parent, one, 0); @@ -129,10 +129,10 @@ suite('tree', function() { }); test('disowning the middle', function() { - var parent = Node(); - var leftward = Node(); - var rightward = Node(); - var middle = Node(); + var parent = new Node(); + var leftward = new Node(); + var rightward = new Node(); + var middle = new Node(); leftward.adopt(parent, 0, 0); rightward.adopt(parent, leftward, 0); @@ -166,17 +166,17 @@ suite('tree', function() { test('half-empty fragments are disallowed', function() { assert.throws(function() { - Fragment(Node(), 0) + Fragment(new Node(), 0) }, 'half-empty on the right'); assert.throws(function() { - Fragment(0, Node()); + Fragment(0, new Node()); }, 'half-empty on the left'); }); test('directionalized constructor call', function() { - var ChNode = P(Node, { init: function(ch) { this.ch = ch; } }); - var parent = Node(); + var ChNode = P(Node, { init: function(ch) { this.initBaseNode(); this.ch = ch; } }); + var parent = new Node(); var a = ChNode('a').adopt(parent, parent.ends[R], 0); var b = ChNode('b').adopt(parent, parent.ends[R], 0); var c = ChNode('c').adopt(parent, parent.ends[R], 0); @@ -192,9 +192,9 @@ suite('tree', function() { }); test('disown is idempotent', function() { - var parent = Node(); - var one = Node().adopt(parent, 0, 0); - var two = Node().adopt(parent, one, 0); + var parent = new Node(); + var one = new Node().adopt(parent, 0, 0); + var two = new Node().adopt(parent, one, 0); var frag = Fragment(one, two); frag.disown(); From 8917422ca69de865d7dc35fb382a24190023b8d8 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 11:13:23 -0500 Subject: [PATCH 004/192] convert Fragment to ES6 class --- src/commands/math/basicSymbols.js | 8 +++---- src/commands/math/commands.js | 8 +++---- src/commands/text.js | 2 +- src/services/keystroke.js | 4 ++-- src/tree.js | 40 +++++++++++++++---------------- test/unit/select.test.js | 2 +- test/unit/tree.test.js | 25 +++++++++++-------- 7 files changed, 47 insertions(+), 42 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 45b16c62d..d9a2d2d01 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -283,7 +283,7 @@ var Letter = P(Variable, function(_, super_) { while (str.length) { if (autoCmds.hasOwnProperty(str)) { for (var i = 1, l = this; i < str.length; i += 1, l = l[L]); - Fragment(l, this).remove(); + new Fragment(l, this).remove(); cursor[L] = l[L]; return LatexCmds[str](str).createLeftOf(cursor); } @@ -357,7 +357,7 @@ var Letter = P(Variable, function(_, super_) { // removeClass and delete flags from all letters before figuring out // which, if any, are part of an operator name - Fragment(l[R] || this.parent.ends[L], r[L] || this.parent.ends[R]).each(function(el) { + new Fragment(l[R] || this.parent.ends[L], r[L] || this.parent.ends[R]).each(function(el) { el.italicize(true).jQ.removeClass('mq-first mq-last mq-followed-by-supsub'); el.ctrlSeq = el.letter; }); @@ -859,7 +859,7 @@ var To = P(BinaryOperator, function(_, super_) { _.deleteTowards = function(dir, cursor) { if (dir === L) { var l = cursor[L]; - Fragment(l, this).remove(); + new Fragment(l, this).remove(); cursor[L] = l[L]; LatexCmds['−']().createLeftOf(cursor); cursor[L].bubble(function (node) { node.reflow(); }); @@ -972,7 +972,7 @@ var Approx = P(BinaryOperator, function(_, super_) { _.deleteTowards = function(dir, cursor) { if (dir === L) { var l = cursor[L]; - Fragment(l, this).remove(); + new Fragment(l, this).remove(); cursor[L] = l[L]; Sim().createLeftOf(cursor); cursor[L].bubble(function (node) { node.reflow(); }); diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index ddcac220e..597b8c891 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -689,7 +689,7 @@ CharCmds['/'] = P(Fraction, function(_, super_) { } if (leftward !== cursor[L] && !cursor.isTooDeep(1)) { - this.replaces(Fragment(leftward[R] || cursor.parent.ends[L], cursor[L])); + this.replaces(new Fragment(leftward[R] || cursor.parent.ends[L], cursor[L])); cursor[L] = leftward; } } @@ -905,7 +905,7 @@ var Bracket = P(P(MathCommand, DelimsMixin), function(_, super_) { var side = this.side = -brack.side; // may be pipe with .side not yet set this.closeOpposing(brack); if (brack === cursor.parent.parent && cursor[side]) { // move the stuff between - Fragment(cursor[side], cursor.parent.ends[side], -side) // me and ghost outside + new Fragment(cursor[side], cursor.parent.ends[side], -side) // me and ghost outside .disown().withDirAdopt(-side, brack.parent, brack, brack[side]) .jQ.insDirOf(side, brack.jQ); } @@ -915,7 +915,7 @@ var Bracket = P(P(MathCommand, DelimsMixin), function(_, super_) { brack = this, side = brack.side; if (brack.replacedFragment) brack.side = 0; // wrapping seln, don't be one-sided else if (cursor[-side]) { // elsewise, auto-expand so ghost is at far end - brack.replaces(Fragment(cursor[-side], cursor.parent.ends[-side], side)); + brack.replaces(new Fragment(cursor[-side], cursor.parent.ends[-side], side)); cursor[-side] = 0; } super_.createLeftOf.call(brack, cursor); @@ -967,7 +967,7 @@ var Bracket = P(P(MathCommand, DelimsMixin), function(_, super_) { } if (sib) { // auto-expand so ghost is at far end var origEnd = this.ends[L].ends[side]; - Fragment(sib, farEnd, -side).disown() + new Fragment(sib, farEnd, -side).disown() .withDirAdopt(-side, this.ends[L], origEnd, 0) .jQ.insAtDirEnd(side, this.ends[L].jQ.removeClass('mq-empty')); if (origEnd.siblingCreated) origEnd.siblingCreated(cursor.options, side); diff --git a/src/commands/text.js b/src/commands/text.js index 12d144a2e..ece3d1c25 100644 --- a/src/commands/text.js +++ b/src/commands/text.js @@ -49,7 +49,7 @@ var TextBlock = P(Node, function(_, super_) { return optWhitespace .then(string('{')).then(regex(/^[^}]*/)).skip(string('}')) .map(function(text) { - if (text.length === 0) return Fragment(); + if (text.length === 0) return new Fragment(); TextPiece(text).adopt(textBlock, 0, 0); return textBlock; diff --git a/src/services/keystroke.js b/src/services/keystroke.js index c10c9ad1d..d66d4769b 100644 --- a/src/services/keystroke.js +++ b/src/services/keystroke.js @@ -324,9 +324,9 @@ Controller.open(function(_) { this.notify('edit'); var fragRemoved; if (dir === L) { - fragRemoved = Fragment(cursor.parent.ends[L], cursor[L]); + fragRemoved = new Fragment(cursor.parent.ends[L], cursor[L]); } else { - fragRemoved = Fragment(cursor[R], cursor.parent.ends[R]); + fragRemoved = new Fragment(cursor[R], cursor.parent.ends[R]); } aria.queue(fragRemoved); fragRemoved.remove(); diff --git a/src/tree.js b/src/tree.js index 8ce9385e2..28c459f80 100644 --- a/src/tree.js +++ b/src/tree.js @@ -177,7 +177,7 @@ class NodeBase { // any extensions that define an init method can call // this version instead of completely overwriting it - initBaseNode () { + init () { this[L] = 0; this[R] = 0 this.parent = 0; @@ -193,11 +193,6 @@ class NodeBase { this.ends[R] = 0; }; - // PJS expects a init method - init () { - this.initBaseNode(); - } - constructor () { this.init(); } @@ -294,7 +289,7 @@ class NodeBase { }; children () { - return Fragment(this.ends[L], this.ends[R]); + return new Fragment(this.ends[L], this.ends[R]); }; eachChild (yield_) { @@ -307,17 +302,17 @@ class NodeBase { }; withDirAdopt (dir, parent, withDir, oppDir) { - Fragment(this, this).withDirAdopt(dir, parent, withDir, oppDir); + new Fragment(this, this).withDirAdopt(dir, parent, withDir, oppDir); return this; }; adopt (parent, leftward, rightward) { - Fragment(this, this).adopt(parent, leftward, rightward); + new Fragment(this, this).adopt(parent, leftward, rightward); return this; }; disown () { - Fragment(this, this).disown(); + new Fragment(this, this).disown(); return this; }; @@ -385,8 +380,10 @@ function prayWellFormed(parent, leftward, rightward) { * DocumentFragment, whose contents must be detached from the visible tree * and have their 'parent' pointers set to the DocumentFragment). */ -var Fragment = P(function(_) { - _.init = function(withDir, oppDir, dir) { +class Fragment { + init (withDir, oppDir, dir) { + this.jQ = $(); + if (dir === undefined) dir = L; prayDirection(dir); @@ -418,14 +415,17 @@ var Fragment = P(function(_) { this.jQ = this.jQ.add(accum); }; - _.jQ = $(); + + constructor (withDir, oppDir, dir) { + this.init(withDir, oppDir, dir); + } // like Cursor::withDirInsertAt(dir, parent, withDir, oppDir) - _.withDirAdopt = function(dir, parent, withDir, oppDir) { + withDirAdopt (dir, parent, withDir, oppDir) { return (dir === L ? this.adopt(parent, withDir, oppDir) : this.adopt(parent, oppDir, withDir)); }; - _.adopt = function(parent, leftward, rightward) { + adopt (parent, leftward, rightward) { prayWellFormed(parent, leftward, rightward); var self = this; @@ -462,7 +462,7 @@ var Fragment = P(function(_) { return self; }; - _.disown = function() { + disown () { var self = this; var leftEnd = self.ends[L]; @@ -492,20 +492,20 @@ var Fragment = P(function(_) { return self; }; - _.remove = function() { + remove () { this.jQ.remove(); return this.disown(); }; - _.each = function (yield_) { + each (yield_) { eachNode(this.ends, yield_); return this; }; - _.fold = function (fold, yield_) { + fold (fold, yield_) { return foldNodes(this.ends, fold, yield_); }; -}); +} /** diff --git a/test/unit/select.test.js b/test/unit/select.test.js index 02e73c8a1..6bf677fb6 100644 --- a/test/unit/select.test.js +++ b/test/unit/select.test.js @@ -3,7 +3,7 @@ suite('Cursor::select()', function() { cursor.selectionChanged = noop; function assertSelection(A, B, leftEnd, rightEnd) { - var lca = leftEnd.parent, frag = Fragment(leftEnd, rightEnd || leftEnd); + var lca = leftEnd.parent, frag = new Fragment(leftEnd, rightEnd || leftEnd); (function eitherOrder(A, B) { diff --git a/test/unit/tree.test.js b/test/unit/tree.test.js index 5a30395e8..934825f81 100644 --- a/test/unit/tree.test.js +++ b/test/unit/tree.test.js @@ -156,7 +156,7 @@ suite('tree', function() { suite('fragments', function() { test('an empty fragment', function() { - var empty = Fragment(); + var empty = new Fragment(); var count = 0; empty.each(function() { count += 1 }); @@ -166,16 +166,21 @@ suite('tree', function() { test('half-empty fragments are disallowed', function() { assert.throws(function() { - Fragment(new Node(), 0) + new Fragment(new Node(), 0) }, 'half-empty on the right'); assert.throws(function() { - Fragment(0, new Node()); + new Fragment(0, new Node()); }, 'half-empty on the left'); }); test('directionalized constructor call', function() { - var ChNode = P(Node, { init: function(ch) { this.initBaseNode(); this.ch = ch; } }); + var ChNode = P(Node, function (_, super_) { + _.init = function(ch) { + super_.init.call(this); + this.ch = ch; + } + }); var parent = new Node(); var a = ChNode('a').adopt(parent, parent.ends[R], 0); var b = ChNode('b').adopt(parent, parent.ends[R], 0); @@ -184,11 +189,11 @@ suite('tree', function() { var e = ChNode('e').adopt(parent, parent.ends[R], 0); function cat(str, node) { return str + node.ch; } - assert.equal('bcd', Fragment(b, d).fold('', cat)); - assert.equal('bcd', Fragment(b, d, L).fold('', cat)); - assert.equal('bcd', Fragment(d, b, R).fold('', cat)); - assert.throws(function() { Fragment(d, b, L); }); - assert.throws(function() { Fragment(b, d, R); }); + assert.equal('bcd', new Fragment(b, d).fold('', cat)); + assert.equal('bcd', new Fragment(b, d, L).fold('', cat)); + assert.equal('bcd', new Fragment(d, b, R).fold('', cat)); + assert.throws(function() { new Fragment(d, b, L); }); + assert.throws(function() { new Fragment(b, d, R); }); }); test('disown is idempotent', function() { @@ -196,7 +201,7 @@ suite('tree', function() { var one = new Node().adopt(parent, 0, 0); var two = new Node().adopt(parent, one, 0); - var frag = Fragment(one, two); + var frag = new Fragment(one, two); frag.disown(); frag.disown(); }); From eff2a3968ab481559df6394f1fb5dd20aedb7fdf Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 11:19:29 -0500 Subject: [PATCH 005/192] convert Cursor to ES6 cclass --- src/controller.js | 2 +- src/cursor.js | 53 ++++++++++++++++++++++------------------ test/unit/select.test.js | 2 +- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/controller.js b/src/controller.js index 3d2b999f3..13ee58672 100644 --- a/src/controller.js +++ b/src/controller.js @@ -20,7 +20,7 @@ var Controller = P(function(_) { root.controller = this; - this.cursor = root.cursor = Cursor(root, options, this); + this.cursor = root.cursor = new Cursor(root, options, this); // TODO: stop depending on root.cursor, and rm it }; diff --git a/src/cursor.js b/src/cursor.js index 3df5ac0b6..f03721451 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -10,8 +10,13 @@ textbox, but any one HTML document can contain many such textboxes, so any one JS environment could actually contain many instances. */ //A fake cursor in the fake textbox that the math is rendered in. -var Cursor = P(Point, function(_) { - _.init = function(initParent, options, controller) { +class Cursor extends Point { + constructor (initParent, options, controller) { + super(); + this.init(initParent, options, controller); + } + + init (initParent, options, controller) { this.controller = controller; this.parent = initParent; this.options = options; @@ -23,7 +28,7 @@ var Cursor = P(Point, function(_) { this.upDownCache = {}; }; - _.show = function() { + show () { this.jQ = this._jQ.removeClass('mq-blink'); if ('intervalId' in this) //already was shown, just restart interval clearInterval(this.intervalId); @@ -41,7 +46,7 @@ var Cursor = P(Point, function(_) { this.intervalId = setInterval(this.blink, 500); return this; }; - _.hide = function() { + hide () { if ('intervalId' in this) clearInterval(this.intervalId); delete this.intervalId; @@ -50,7 +55,7 @@ var Cursor = P(Point, function(_) { return this; }; - _.withDirInsertAt = function(dir, parent, withDir, oppDir) { + withDirInsertAt (dir, parent, withDir, oppDir) { var oldParent = this.parent; this.parent = parent; this[dir] = withDir; @@ -60,25 +65,25 @@ var Cursor = P(Point, function(_) { // FIXME pass cursor to .blur() so text can fix cursor pointers when removing itself if (oldParent !== parent && oldParent.blur) oldParent.blur(this); }; - _.insDirOf = function(dir, el) { + insDirOf (dir, el) { prayDirection(dir); this.jQ.insDirOf(dir, el.jQ); this.withDirInsertAt(dir, el.parent, el[dir], el); this.parent.jQ.addClass('mq-hasCursor'); return this; }; - _.insLeftOf = function(el) { return this.insDirOf(L, el); }; - _.insRightOf = function(el) { return this.insDirOf(R, el); }; + insLeftOf (el) { return this.insDirOf(L, el); }; + insRightOf (el) { return this.insDirOf(R, el); }; - _.insAtDirEnd = function(dir, el) { + insAtDirEnd (dir, el) { prayDirection(dir); this.jQ.insAtDirEnd(dir, el.jQ); this.withDirInsertAt(dir, el, 0, el.ends[dir]); el.focus(); return this; }; - _.insAtLeftEnd = function(el) { return this.insAtDirEnd(L, el); }; - _.insAtRightEnd = function(el) { return this.insAtDirEnd(R, el); }; + insAtLeftEnd (el) { return this.insAtDirEnd(L, el); }; + insAtRightEnd (el) { return this.insAtDirEnd(R, el); }; /** * jump up or down from one block Node to another: @@ -88,7 +93,7 @@ var Cursor = P(Point, function(_) { * + if not seek a position in the node that is horizontally closest to * the cursor's current position */ - _.jumpUpDown = function(from, to) { + jumpUpDown (from, to) { var self = this; self.upDownCache[from.id] = Point.copy(self); var cached = self.upDownCache[to.id]; @@ -101,7 +106,7 @@ var Cursor = P(Point, function(_) { } aria.queue(to, true); }; - _.offset = function() { + offset () { //in Opera 11.62, .getBoundingClientRect() and hence jQuery::offset() //returns all 0's on inline elements with negative margin-right (like //the cursor) at the end of their parent, so temporarily remove the @@ -113,7 +118,7 @@ var Cursor = P(Point, function(_) { self.jQ.addClass('mq-cursor'); return offset; } - _.unwrapGramp = function() { + unwrapGramp () { var gramp = this.parent.parent; var greatgramp = gramp.parent; var rightward = gramp[R]; @@ -159,7 +164,7 @@ var Cursor = P(Point, function(_) { if (gramp[L].siblingDeleted) gramp[L].siblingDeleted(cursor.options, R); if (gramp[R].siblingDeleted) gramp[R].siblingDeleted(cursor.options, L); }; - _.startSelection = function() { + startSelection () { var anticursor = this.anticursor = Point.copy(this); var ancestors = anticursor.ancestors = {}; // a map from each ancestor of // the anticursor, to its child that is also an ancestor; in other words, @@ -168,10 +173,10 @@ var Cursor = P(Point, function(_) { ancestors[ancestor.parent.id] = ancestor; } }; - _.endSelection = function() { + endSelection () { delete this.anticursor; }; - _.select = function() { + select () { var anticursor = this.anticursor; if (this[L] === anticursor[L] && this.parent === anticursor.parent) return false; @@ -234,14 +239,14 @@ var Cursor = P(Point, function(_) { this.selectionChanged(); return true; }; - _.resetToEnd = function (controller) { + resetToEnd (controller) { this.clearSelection(); var root = controller.root; this[R] = 0; this[L] = root.ends[R]; this.parent = root; }; - _.clearSelection = function() { + clearSelection () { if (this.selection) { this.selection.clear(); delete this.selection; @@ -249,7 +254,7 @@ var Cursor = P(Point, function(_) { } return this; }; - _.deleteSelection = function() { + deleteSelection () { if (!this.selection) return; this[L] = this.selection.ends[L][L]; @@ -258,7 +263,7 @@ var Cursor = P(Point, function(_) { this.selectionChanged(); delete this.selection; }; - _.replaceSelection = function() { + replaceSelection () { var seln = this.selection; if (seln) { this[L] = seln.ends[L][L]; @@ -267,7 +272,7 @@ var Cursor = P(Point, function(_) { } return seln; }; - _.depth = function() { + depth () { var node = this; var depth = 0; while (node = node.parent) { @@ -275,12 +280,12 @@ var Cursor = P(Point, function(_) { } return depth; }; - _.isTooDeep = function(offset) { + isTooDeep (offset) { if (this.options.maxDepth !== undefined) { return this.depth() + (offset || 0) > this.options.maxDepth; } }; -}); +} var Selection = P(Fragment, function(_, super_) { _.init = function() { diff --git a/test/unit/select.test.js b/test/unit/select.test.js index 6bf677fb6..200823f57 100644 --- a/test/unit/select.test.js +++ b/test/unit/select.test.js @@ -1,5 +1,5 @@ suite('Cursor::select()', function() { - var cursor = Cursor(); + var cursor = new Cursor(); cursor.selectionChanged = noop; function assertSelection(A, B, leftEnd, rightEnd) { From 16d268d81539acf1b5dac6726b194146855a6608 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 11:27:19 -0500 Subject: [PATCH 006/192] convert MathElement and Selection to ES6 class --- src/commands/math.js | 12 ++++++------ src/cursor.js | 17 +++++++++-------- src/tree.js | 8 ++------ 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/commands/math.js b/src/commands/math.js index 48bfd0e8d..a0333e108 100644 --- a/src/commands/math.js +++ b/src/commands/math.js @@ -7,8 +7,8 @@ * Some math-tree-specific extensions to Node. * Both MathBlock's and MathCommand's descend from it. */ -var MathElement = P(Node, function(_, super_) { - _.finalizeInsert = function(options, cursor) { // `cursor` param is only for +class MathElement extends Node { + finalizeInsert (options, cursor) { // `cursor` param is only for // SupSub::contactWeld, and is deliberately only passed in by writeLatex, // see ea7307eb4fac77c149a11ffdf9a831df85247693 var self = this; @@ -29,7 +29,7 @@ var MathElement = P(Node, function(_, super_) { // If the maxDepth option is set, make sure // deeply nested content is truncated. Just return // false if the cursor is already too deep. - _.prepareInsertionAt = function(cursor) { + prepareInsertionAt (cursor) { var maxDepth = cursor.options.maxDepth; if (maxDepth !== undefined) { var cursorDepth = cursor.depth(); @@ -42,7 +42,7 @@ var MathElement = P(Node, function(_, super_) { }; // Remove nodes that are more than `cutoff` // blocks deep from this node. - _.removeNodesDeeperThan = function (cutoff) { + removeNodesDeeperThan (cutoff) { var depth = 0; var queue = [[this, depth]]; var current; @@ -63,7 +63,7 @@ var MathElement = P(Node, function(_, super_) { }); } }; -}); +} /** * Commands and operators, like subscripts, exponents, or fractions. @@ -156,7 +156,7 @@ var MathCommand = P(MathElement, function(_, super_) { cursor[dir] = this[dir]; }; _.selectChildren = function() { - return Selection(this, this); + return new Selection(this, this); }; _.unselectInto = function(dir, cursor) { cursor.insAtDirEnd(-dir, cursor.anticursor.ancestors[this.id]); diff --git a/src/cursor.js b/src/cursor.js index f03721451..2cb1ea0a7 100644 --- a/src/cursor.js +++ b/src/cursor.js @@ -287,26 +287,27 @@ class Cursor extends Point { }; } -var Selection = P(Fragment, function(_, super_) { - _.init = function() { - super_.init.apply(this, arguments); +class Selection extends Fragment { + constructor (withDir, oppDir, dir) { + super(withDir, oppDir, dir); + this.jQ = this.jQ.wrapAll('').parent(); //can't do wrapAll(this.jQ = $(...)) because wrapAll will clone it }; - _.adopt = function() { + adopt () { this.jQ.replaceWith(this.jQ = this.jQ.children()); - return super_.adopt.apply(this, arguments); + return super.adopt.apply(this, arguments); }; - _.clear = function() { + clear () { // using the browser's native .childNodes property so that we // don't discard text nodes. this.jQ.replaceWith(this.jQ[0].childNodes); return this; }; - _.join = function(methodName, separatorToken) { + join (methodName, separatorToken) { var separator = separatorToken || ''; return this.fold('', function(fold, child) { return fold + separator + child[methodName](); }); }; -}); +}; diff --git a/src/tree.js b/src/tree.js index 28c459f80..950319d02 100644 --- a/src/tree.js +++ b/src/tree.js @@ -243,7 +243,7 @@ class NodeBase { createLeftOf (el) { return this.createDir(L, el); }; selectChildren (leftEnd, rightEnd) { - return Selection(leftEnd, rightEnd); + return new Selection(leftEnd, rightEnd); }; bubble (yield_) { @@ -381,7 +381,7 @@ function prayWellFormed(parent, leftward, rightward) { * and have their 'parent' pointers set to the DocumentFragment). */ class Fragment { - init (withDir, oppDir, dir) { + constructor (withDir, oppDir, dir) { this.jQ = $(); if (dir === undefined) dir = L; @@ -416,10 +416,6 @@ class Fragment { this.jQ = this.jQ.add(accum); }; - constructor (withDir, oppDir, dir) { - this.init(withDir, oppDir, dir); - } - // like Cursor::withDirInsertAt(dir, parent, withDir, oppDir) withDirAdopt (dir, parent, withDir, oppDir) { return (dir === L ? this.adopt(parent, withDir, oppDir) From d74c2ef373841cacfee97f2e5f2cb3fa1087f5c2 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 12:28:51 -0500 Subject: [PATCH 007/192] convert MathCommand to ES6 class. --- src/commands/math.js | 56 +++++++++++++++++++---------------- src/commands/math/commands.js | 2 +- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/commands/math.js b/src/commands/math.js index a0333e108..84140bfc8 100644 --- a/src/commands/math.js +++ b/src/commands/math.js @@ -69,28 +69,34 @@ class MathElement extends Node { * Commands and operators, like subscripts, exponents, or fractions. * Descendant commands are organized into blocks. */ -var MathCommand = P(MathElement, function(_, super_) { - _.init = function(ctrlSeq, htmlTemplate, textTemplate) { +class MathCommand extends MathElement { + constructor (ctrlSeq, htmlTemplate, textTemplate) { + super(); + this.init(ctrlSeq, htmlTemplate, textTemplate); + }; + + init (ctrlSeq, htmlTemplate, textTemplate) { + super.init(); + var cmd = this; - super_.init.call(cmd); if (!cmd.ctrlSeq) cmd.ctrlSeq = ctrlSeq; if (htmlTemplate) cmd.htmlTemplate = htmlTemplate; if (textTemplate) cmd.textTemplate = textTemplate; - }; + } // obvious methods - _.replaces = function(replacedFragment) { + replaces (replacedFragment) { replacedFragment.disown(); this.replacedFragment = replacedFragment; }; - _.isEmpty = function() { + isEmpty () { return this.foldChildren(true, function(isEmpty, child) { return isEmpty && child.isEmpty(); }); }; - _.parser = function() { + parser () { var block = latexMathParser.block; var self = this; @@ -106,12 +112,12 @@ var MathCommand = P(MathElement, function(_, super_) { }; // createLeftOf(cursor) and the methods it calls - _.createLeftOf = function(cursor) { + createLeftOf (cursor) { var cmd = this; var replacedFragment = cmd.replacedFragment; cmd.createBlocks(); - super_.createLeftOf.call(cmd, cursor); + super.createLeftOf.call(cmd, cursor); if (replacedFragment) { replacedFragment.adopt(cmd.ends[L], 0, 0); replacedFragment.jQ.appendTo(cmd.ends[L].jQ); @@ -121,7 +127,7 @@ var MathCommand = P(MathElement, function(_, super_) { cmd.finalizeInsert(cursor.options); cmd.placeCursor(cursor); }; - _.createBlocks = function() { + createBlocks () { var cmd = this, numBlocks = cmd.numBlocks(), blocks = cmd.blocks = Array(numBlocks); @@ -131,7 +137,7 @@ var MathCommand = P(MathElement, function(_, super_) { newBlock.adopt(cmd, cmd.ends[R], 0); } }; - _.placeCursor = function(cursor) { + placeCursor (cursor) { //insert the cursor at the right end of the first empty child, searching //left-to-right, or if none empty, the right end child cursor.insAtRightEnd(this.foldChildren(this.ends[L], function(leftward, child) { @@ -142,26 +148,26 @@ var MathCommand = P(MathElement, function(_, super_) { // editability methods: called by the cursor for editing, cursor movements, // and selection of the MathQuill tree, these all take in a direction and // the cursor - _.moveTowards = function(dir, cursor, updown) { + moveTowards (dir, cursor, updown) { var updownInto = updown && this[updown+'Into']; cursor.insAtDirEnd(-dir, updownInto || this.ends[-dir]); aria.queueDirEndOf(-dir).queue(cursor.parent, true); }; - _.deleteTowards = function(dir, cursor) { + deleteTowards (dir, cursor) { if (this.isEmpty()) cursor[dir] = this.remove()[dir]; else this.moveTowards(dir, cursor, null); }; - _.selectTowards = function(dir, cursor) { + selectTowards (dir, cursor) { cursor[-dir] = this; cursor[dir] = this[dir]; }; - _.selectChildren = function() { + selectChildren () { return new Selection(this, this); }; - _.unselectInto = function(dir, cursor) { + unselectInto (dir, cursor) { cursor.insAtDirEnd(-dir, cursor.anticursor.ancestors[this.id]); }; - _.seek = function(pageX, cursor) { + seek (pageX, cursor) { function getBounds(node) { var bounds = {} bounds[L] = node.jQ.offset().left; @@ -230,11 +236,11 @@ var MathCommand = P(MathElement, function(_, super_) { Note that & isn't well-formed HTML; if you wanted a literal '&123', your HTML template would have to have '&123'. */ - _.numBlocks = function() { + numBlocks () { var matches = this.htmlTemplate.match(/&\d+/g); return matches ? matches.length : 0; }; - _.html = function() { + html () { // Render the entire math subtree rooted at this command, as HTML. // Expects .createBlocks() to have been called already, since it uses the // .blocks array of child blocks. @@ -313,13 +319,13 @@ var MathCommand = P(MathElement, function(_, super_) { }; // methods to export a string representation of the math tree - _.latex = function() { + latex () { return this.foldChildren(this.ctrlSeq, function(latex, child) { return latex + '{' + (child.latex() || ' ') + '}'; }); }; - _.textTemplate = ['']; - _.text = function() { + static _todoMoveIntoConstructor = MathCommand.prototype.textTemplate = ['']; + text () { var cmd = this, i = 0; return cmd.foldChildren(cmd.textTemplate[i], function(text, child) { i += 1; @@ -330,15 +336,15 @@ var MathCommand = P(MathElement, function(_, super_) { return text + child_text + (cmd.textTemplate[i] || ''); }); }; - _.mathspeakTemplate = []; - _.mathspeak = function() { + static _todoMoveIntoConstructor = MathCommand.prototype.mathspeakTemplate = ['']; + mathspeak () { var cmd = this, i = 0; return cmd.foldChildren(cmd.mathspeakTemplate[i] || 'Start'+cmd.ctrlSeq+' ', function(speech, block) { i += 1; return speech + ' ' + block.mathspeak() + ' ' + (cmd.mathspeakTemplate[i]+' ' || 'End'+cmd.ctrlSeq+' '); }); }; -}); +}; /** * Lightweight command without blocks or children. diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 597b8c891..3e5f9bc91 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -548,7 +548,7 @@ LatexCmds.integral = P(SummationNotation, function(_, super_) { Symbol.prototype.init.call(this, '\\int ', htmlTemplate, 'integral'); }; // FIXME: refactor rather than overriding - _.createLeftOf = MathCommand.p.createLeftOf; + _.createLeftOf = MathCommand.prototype.createLeftOf; }); var Fraction = LatexCmds.frac = From b6ea07a30aea135696f18417b1147dcfbc6eed63 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 12:58:11 -0500 Subject: [PATCH 008/192] convert Symbol to ES6 class --- src/commands/math.js | 37 ++++++++++++++++++------------- src/commands/math/basicSymbols.js | 2 +- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/commands/math.js b/src/commands/math.js index 84140bfc8..49df2cf4b 100644 --- a/src/commands/math.js +++ b/src/commands/math.js @@ -349,32 +349,37 @@ class MathCommand extends MathElement { /** * Lightweight command without blocks or children. */ -var Symbol = P(MathCommand, function(_, super_) { - _.init = function(ctrlSeq, html, text, mathspeak) { +class Symbol extends MathCommand { + constructor (ctrlSeq, html, text, mathspeak) { + super(ctrlSeq, html, text); + this.init(ctrlSeq, html, text, mathspeak); + } + + init (ctrlSeq, html, text, mathspeak) { if (!text && !!ctrlSeq) text = ctrlSeq.replace(/^\\/, ''); this.mathspeakName = mathspeak || text; - super_.init.call(this, ctrlSeq, html, [ text ]); + super.init(ctrlSeq, html, [ text ]); }; - _.parser = function() { return Parser.succeed(this); }; - _.numBlocks = function() { return 0; }; + parser () { return Parser.succeed(this); }; + numBlocks () { return 0; }; - _.replaces = function(replacedFragment) { + replaces (replacedFragment) { replacedFragment.remove(); }; - _.createBlocks = noop; + createBlocks () {}; - _.moveTowards = function(dir, cursor) { + moveTowards (dir, cursor) { cursor.jQ.insDirOf(dir, this.jQ); cursor[-dir] = this; cursor[dir] = this[dir]; aria.queue(this); }; - _.deleteTowards = function(dir, cursor) { + deleteTowards (dir, cursor) { cursor[dir] = this.remove()[dir]; }; - _.seek = function(pageX, cursor) { + seek (pageX, cursor) { // insert at whichever side the click was closer to if (pageX - this.jQ.offset().left < this.jQ.outerWidth()/2) cursor.insLeftOf(this); @@ -382,12 +387,12 @@ var Symbol = P(MathCommand, function(_, super_) { cursor.insRightOf(this); }; - _.latex = function(){ return this.ctrlSeq; }; - _.text = function(){ return this.textTemplate.join(''); }; - _.mathspeak = function(){ return this.mathspeakName; }; - _.placeCursor = noop; - _.isEmpty = function(){ return true; }; -}); + latex (){ return this.ctrlSeq; }; + text (){ return this.textTemplate.join(''); }; + mathspeak (){ return this.mathspeakName; }; + placeCursor () {}; + isEmpty (){ return true; }; +}; var VanillaSymbol = P(Symbol, function(_, super_) { _.init = function(ch, html, mathspeak) { super_.init.call(this, ch, ''+(html || ch)+'', undefined, mathspeak); diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index d9a2d2d01..fafa55db5 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -533,7 +533,7 @@ LatexCmds.operatorname = P(MathCommand, function(_) { LatexCmds.f = P(Letter, function(_, super_) { _.init = function() { - Symbol.p.init.call(this, this.letter = 'f', 'f'); + Symbol.prototype.init.call(this, this.letter = 'f', 'f'); }; _.italicize = function(bool) { this.jQ.html('f').toggleClass('mq-f', bool); From a5ddd2fe223a6930c44c22958165cbf661216583 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 14:03:20 -0500 Subject: [PATCH 009/192] convert VanillaSymbol to ES6 class --- src/commands/math.js | 21 +- src/commands/math/LatexCommandInput.js | 2 +- src/commands/math/advancedSymbols.js | 268 ++++++++++++------------- src/commands/math/basicSymbols.js | 20 +- src/commands/text.js | 6 +- src/services/latex.js | 4 +- 6 files changed, 165 insertions(+), 156 deletions(-) diff --git a/src/commands/math.js b/src/commands/math.js index 49df2cf4b..fa410c971 100644 --- a/src/commands/math.js +++ b/src/commands/math.js @@ -393,11 +393,19 @@ class Symbol extends MathCommand { placeCursor () {}; isEmpty (){ return true; }; }; -var VanillaSymbol = P(Symbol, function(_, super_) { - _.init = function(ch, html, mathspeak) { - super_.init.call(this, ch, ''+(html || ch)+'', undefined, mathspeak); +class VanillaSymbol extends Symbol { + constructor (ch, html, mathspeak) { + super(); + this.init(ch, html, mathspeak); + } + init (ch, html, mathspeak) { + super.init(ch, ''+(html || ch)+'', undefined, mathspeak); }; -}); +} +function bindVanillaSymbol (ch, html, mathspeak) { + return () => new VanillaSymbol(ch, html, mathspeak); +} + var BinaryOperator = P(Symbol, function(_, super_) { _.init = function(ctrlSeq, html, text, mathspeak) { super_.init.call(this, @@ -517,10 +525,11 @@ var MathBlock = P(MathElement, function(_, super_) { return LatexCmds['×'](ch); else if (options && options.typingPercentWritesPercentOf && ch === '%') return LatexCmds.percentof(ch); - else if (cons = CharCmds[ch] || LatexCmds[ch]) + else if (cons = CharCmds[ch] || LatexCmds[ch]) { return cons(ch); + } else - return VanillaSymbol(ch); + return new VanillaSymbol(ch); }; _.write = function(cursor, ch) { var cmd = this.chToCmd(ch, cursor.options); diff --git a/src/commands/math/LatexCommandInput.js b/src/commands/math/LatexCommandInput.js index dca839ab7..188e20e23 100644 --- a/src/commands/math/LatexCommandInput.js +++ b/src/commands/math/LatexCommandInput.js @@ -31,7 +31,7 @@ CharCmds['\\'] = P(MathCommand, function(_, super_) { cursor.show().deleteSelection(); if (ch.match(/[a-z]/i)) { - VanillaSymbol(ch).createLeftOf(cursor); + new VanillaSymbol(ch).createLeftOf(cursor); // TODO needs tests aria.alert(ch); } diff --git a/src/commands/math/advancedSymbols.js b/src/commands/math/advancedSymbols.js index 865edfc9c..9f3f4fcef 100644 --- a/src/commands/math/advancedSymbols.js +++ b/src/commands/math/advancedSymbols.js @@ -88,35 +88,35 @@ LatexCmds.mathbb = P(MathCommand, function(_) { }); LatexCmds.N = LatexCmds.naturals = LatexCmds.Naturals = - bind(VanillaSymbol,'\\mathbb{N}','ℕ', 'naturals'); + bindVanillaSymbol('\\mathbb{N}','ℕ', 'naturals'); LatexCmds.P = LatexCmds.primes = LatexCmds.Primes = LatexCmds.projective = LatexCmds.Projective = LatexCmds.probability = LatexCmds.Probability = - bind(VanillaSymbol,'\\mathbb{P}','ℙ', 'P'); + bindVanillaSymbol('\\mathbb{P}','ℙ', 'P'); LatexCmds.Z = LatexCmds.integers = LatexCmds.Integers = - bind(VanillaSymbol,'\\mathbb{Z}','ℤ', 'integers'); + bindVanillaSymbol('\\mathbb{Z}','ℤ', 'integers'); LatexCmds.Q = LatexCmds.rationals = LatexCmds.Rationals = - bind(VanillaSymbol,'\\mathbb{Q}','ℚ', 'rationals'); + bindVanillaSymbol('\\mathbb{Q}','ℚ', 'rationals'); LatexCmds.R = LatexCmds.reals = LatexCmds.Reals = - bind(VanillaSymbol,'\\mathbb{R}','ℝ', 'reals'); + bindVanillaSymbol('\\mathbb{R}','ℝ', 'reals'); LatexCmds.C = LatexCmds.complex = LatexCmds.Complex = LatexCmds.complexes = LatexCmds.Complexes = LatexCmds.complexplane = LatexCmds.Complexplane = LatexCmds.ComplexPlane = - bind(VanillaSymbol,'\\mathbb{C}','ℂ', 'complexes'); + bindVanillaSymbol('\\mathbb{C}','ℂ', 'complexes'); LatexCmds.H = LatexCmds.Hamiltonian = LatexCmds.quaternions = LatexCmds.Quaternions = - bind(VanillaSymbol,'\\mathbb{H}','ℍ', 'quaternions'); + bindVanillaSymbol('\\mathbb{H}','ℍ', 'quaternions'); //spacing -LatexCmds.quad = LatexCmds.emsp = bind(VanillaSymbol,'\\quad ',' ', '4 spaces'); -LatexCmds.qquad = bind(VanillaSymbol,'\\qquad ',' ', '8 spaces'); +LatexCmds.quad = LatexCmds.emsp = bindVanillaSymbol('\\quad ',' ', '4 spaces'); +LatexCmds.qquad = bindVanillaSymbol('\\qquad ',' ', '8 spaces'); /* spacing special characters, gonna have to implement this in LatexCommandInput::onText somehow case ',': return VanillaSymbol('\\, ',' ', 'comma'); @@ -129,191 +129,191 @@ case '!': */ //binary operators -LatexCmds.diamond = bind(VanillaSymbol, '\\diamond ', '◇', 'diamond'); -LatexCmds.bigtriangleup = bind(VanillaSymbol, '\\bigtriangleup ', '△', 'triangle up'); -LatexCmds.ominus = bind(VanillaSymbol, '\\ominus ', '⊖', 'o minus'); -LatexCmds.uplus = bind(VanillaSymbol, '\\uplus ', '⊎', 'disjoint union'); -LatexCmds.bigtriangledown = bind(VanillaSymbol, '\\bigtriangledown ', '▽', 'triangle down'); -LatexCmds.sqcap = bind(VanillaSymbol, '\\sqcap ', '⊓', 'greatest lower bound'); -LatexCmds.triangleleft = bind(VanillaSymbol, '\\triangleleft ', '⊲', 'triangle left'); -LatexCmds.sqcup = bind(VanillaSymbol, '\\sqcup ', '⊔', 'least upper bound'); -LatexCmds.triangleright = bind(VanillaSymbol, '\\triangleright ', '⊳', 'triangle right'); +LatexCmds.diamond = bindVanillaSymbol('\\diamond ', '◇', 'diamond'); +LatexCmds.bigtriangleup = bindVanillaSymbol('\\bigtriangleup ', '△', 'triangle up'); +LatexCmds.ominus = bindVanillaSymbol('\\ominus ', '⊖', 'o minus'); +LatexCmds.uplus = bindVanillaSymbol('\\uplus ', '⊎', 'disjoint union'); +LatexCmds.bigtriangledown = bindVanillaSymbol('\\bigtriangledown ', '▽', 'triangle down'); +LatexCmds.sqcap = bindVanillaSymbol('\\sqcap ', '⊓', 'greatest lower bound'); +LatexCmds.triangleleft = bindVanillaSymbol('\\triangleleft ', '⊲', 'triangle left'); +LatexCmds.sqcup = bindVanillaSymbol('\\sqcup ', '⊔', 'least upper bound'); +LatexCmds.triangleright = bindVanillaSymbol('\\triangleright ', '⊳', 'triangle right'); //circledot is not a not real LaTex command see https://github.com/mathquill/mathquill/pull/552 for more details -LatexCmds.odot = LatexCmds.circledot = bind(VanillaSymbol, '\\odot ', '⊙', 'circle dot'); -LatexCmds.bigcirc = bind(VanillaSymbol, '\\bigcirc ', '◯', 'circle'); -LatexCmds.dagger = bind(VanillaSymbol, '\\dagger ', '†', 'dagger'); -LatexCmds.ddagger = bind(VanillaSymbol, '\\ddagger ', '‡', 'big dagger'); -LatexCmds.wr = bind(VanillaSymbol, '\\wr ', '≀', 'wreath'); -LatexCmds.amalg = bind(VanillaSymbol, '\\amalg ', '∐', 'amalgam'); +LatexCmds.odot = LatexCmds.circledot = bindVanillaSymbol('\\odot ', '⊙', 'circle dot'); +LatexCmds.bigcirc = bindVanillaSymbol('\\bigcirc ', '◯', 'circle'); +LatexCmds.dagger = bindVanillaSymbol('\\dagger ', '†', 'dagger'); +LatexCmds.ddagger = bindVanillaSymbol('\\ddagger ', '‡', 'big dagger'); +LatexCmds.wr = bindVanillaSymbol('\\wr ', '≀', 'wreath'); +LatexCmds.amalg = bindVanillaSymbol('\\amalg ', '∐', 'amalgam'); //relationship symbols -LatexCmds.models = bind(VanillaSymbol, '\\models ', '⊨', 'models'); -LatexCmds.prec = bind(VanillaSymbol, '\\prec ', '≺', 'precedes'); -LatexCmds.succ = bind(VanillaSymbol, '\\succ ', '≻', 'succeeds'); -LatexCmds.preceq = bind(VanillaSymbol, '\\preceq ', '≼', 'precedes or equals'); -LatexCmds.succeq = bind(VanillaSymbol, '\\succeq ', '≽', 'succeeds or equals'); -LatexCmds.simeq = bind(VanillaSymbol, '\\simeq ', '≃', 'similar or equal to'); -LatexCmds.mid = bind(VanillaSymbol, '\\mid ', '∣', 'divides'); -LatexCmds.ll = bind(VanillaSymbol, '\\ll ', '≪', 'll'); -LatexCmds.gg = bind(VanillaSymbol, '\\gg ', '≫', 'gg'); -LatexCmds.parallel = bind(VanillaSymbol, '\\parallel ', '∥', 'parallel with'); -LatexCmds.nparallel = bind(VanillaSymbol, '\\nparallel ', '∦', 'not parallel with'); -LatexCmds.bowtie = bind(VanillaSymbol, '\\bowtie ', '⋈', 'bowtie'); -LatexCmds.sqsubset = bind(VanillaSymbol, '\\sqsubset ', '⊏', 'square subset'); -LatexCmds.sqsupset = bind(VanillaSymbol, '\\sqsupset ', '⊐', 'square superset'); -LatexCmds.smile = bind(VanillaSymbol, '\\smile ', '⌣', 'smile'); -LatexCmds.sqsubseteq = bind(VanillaSymbol, '\\sqsubseteq ', '⊑', 'square subset or equal to'); -LatexCmds.sqsupseteq = bind(VanillaSymbol, '\\sqsupseteq ', '⊒', 'square superset or equal to'); -LatexCmds.doteq = bind(VanillaSymbol, '\\doteq ', '≐', 'dotted equals'); -LatexCmds.frown = bind(VanillaSymbol, '\\frown ', '⌢', 'frown'); -LatexCmds.vdash = bind(VanillaSymbol, '\\vdash ', '⊦', 'v dash'); -LatexCmds.dashv = bind(VanillaSymbol, '\\dashv ', '⊣', 'dash v'); -LatexCmds.nless = bind(VanillaSymbol, '\\nless ', '≮', 'not less than'); -LatexCmds.ngtr = bind(VanillaSymbol, '\\ngtr ', '≯', 'not greater than'); +LatexCmds.models = bindVanillaSymbol('\\models ', '⊨', 'models'); +LatexCmds.prec = bindVanillaSymbol('\\prec ', '≺', 'precedes'); +LatexCmds.succ = bindVanillaSymbol('\\succ ', '≻', 'succeeds'); +LatexCmds.preceq = bindVanillaSymbol('\\preceq ', '≼', 'precedes or equals'); +LatexCmds.succeq = bindVanillaSymbol('\\succeq ', '≽', 'succeeds or equals'); +LatexCmds.simeq = bindVanillaSymbol('\\simeq ', '≃', 'similar or equal to'); +LatexCmds.mid = bindVanillaSymbol('\\mid ', '∣', 'divides'); +LatexCmds.ll = bindVanillaSymbol('\\ll ', '≪', 'll'); +LatexCmds.gg = bindVanillaSymbol('\\gg ', '≫', 'gg'); +LatexCmds.parallel = bindVanillaSymbol('\\parallel ', '∥', 'parallel with'); +LatexCmds.nparallel = bindVanillaSymbol('\\nparallel ', '∦', 'not parallel with'); +LatexCmds.bowtie = bindVanillaSymbol('\\bowtie ', '⋈', 'bowtie'); +LatexCmds.sqsubset = bindVanillaSymbol('\\sqsubset ', '⊏', 'square subset'); +LatexCmds.sqsupset = bindVanillaSymbol('\\sqsupset ', '⊐', 'square superset'); +LatexCmds.smile = bindVanillaSymbol('\\smile ', '⌣', 'smile'); +LatexCmds.sqsubseteq = bindVanillaSymbol('\\sqsubseteq ', '⊑', 'square subset or equal to'); +LatexCmds.sqsupseteq = bindVanillaSymbol('\\sqsupseteq ', '⊒', 'square superset or equal to'); +LatexCmds.doteq = bindVanillaSymbol('\\doteq ', '≐', 'dotted equals'); +LatexCmds.frown = bindVanillaSymbol('\\frown ', '⌢', 'frown'); +LatexCmds.vdash = bindVanillaSymbol('\\vdash ', '⊦', 'v dash'); +LatexCmds.dashv = bindVanillaSymbol('\\dashv ', '⊣', 'dash v'); +LatexCmds.nless = bindVanillaSymbol('\\nless ', '≮', 'not less than'); +LatexCmds.ngtr = bindVanillaSymbol('\\ngtr ', '≯', 'not greater than'); //arrows -LatexCmds.longleftarrow = bind(VanillaSymbol, '\\longleftarrow ', '←', 'left arrow'); -LatexCmds.longrightarrow = bind(VanillaSymbol, '\\longrightarrow ', '→', 'right arrow'); -LatexCmds.Longleftarrow = bind(VanillaSymbol, '\\Longleftarrow ', '⇐', 'left arrow'); -LatexCmds.Longrightarrow = bind(VanillaSymbol, '\\Longrightarrow ', '⇒', 'right arrow'); -LatexCmds.longleftrightarrow = bind(VanillaSymbol, '\\longleftrightarrow ', '↔', 'left and right arrow'); -LatexCmds.updownarrow = bind(VanillaSymbol, '\\updownarrow ', '↕', 'up and down arrow'); -LatexCmds.Longleftrightarrow = bind(VanillaSymbol, '\\Longleftrightarrow ', '⇔', 'left and right arrow'); -LatexCmds.Updownarrow = bind(VanillaSymbol, '\\Updownarrow ', '⇕', 'up and down arrow'); -LatexCmds.mapsto = bind(VanillaSymbol, '\\mapsto ', '↦', 'maps to'); -LatexCmds.nearrow = bind(VanillaSymbol, '\\nearrow ', '↗', 'northeast arrow'); -LatexCmds.hookleftarrow = bind(VanillaSymbol, '\\hookleftarrow ', '↩', 'hook left arrow'); -LatexCmds.hookrightarrow = bind(VanillaSymbol, '\\hookrightarrow ', '↪', 'hook right arrow'); -LatexCmds.searrow = bind(VanillaSymbol, '\\searrow ', '↘', 'southeast arrow'); -LatexCmds.leftharpoonup = bind(VanillaSymbol, '\\leftharpoonup ', '↼', 'left harpoon up'); -LatexCmds.rightharpoonup = bind(VanillaSymbol, '\\rightharpoonup ', '⇀', 'right harpoon up'); -LatexCmds.swarrow = bind(VanillaSymbol, '\\swarrow ', '↙', 'southwest arrow'); -LatexCmds.leftharpoondown = bind(VanillaSymbol, '\\leftharpoondown ', '↽', 'left harpoon down'); -LatexCmds.rightharpoondown = bind(VanillaSymbol, '\\rightharpoondown ', '⇁', 'right harpoon down'); -LatexCmds.nwarrow = bind(VanillaSymbol, '\\nwarrow ', '↖', 'northwest arrow'); +LatexCmds.longleftarrow = bindVanillaSymbol('\\longleftarrow ', '←', 'left arrow'); +LatexCmds.longrightarrow = bindVanillaSymbol('\\longrightarrow ', '→', 'right arrow'); +LatexCmds.Longleftarrow = bindVanillaSymbol('\\Longleftarrow ', '⇐', 'left arrow'); +LatexCmds.Longrightarrow = bindVanillaSymbol('\\Longrightarrow ', '⇒', 'right arrow'); +LatexCmds.longleftrightarrow = bindVanillaSymbol('\\longleftrightarrow ', '↔', 'left and right arrow'); +LatexCmds.updownarrow = bindVanillaSymbol('\\updownarrow ', '↕', 'up and down arrow'); +LatexCmds.Longleftrightarrow = bindVanillaSymbol('\\Longleftrightarrow ', '⇔', 'left and right arrow'); +LatexCmds.Updownarrow = bindVanillaSymbol('\\Updownarrow ', '⇕', 'up and down arrow'); +LatexCmds.mapsto = bindVanillaSymbol('\\mapsto ', '↦', 'maps to'); +LatexCmds.nearrow = bindVanillaSymbol('\\nearrow ', '↗', 'northeast arrow'); +LatexCmds.hookleftarrow = bindVanillaSymbol('\\hookleftarrow ', '↩', 'hook left arrow'); +LatexCmds.hookrightarrow = bindVanillaSymbol('\\hookrightarrow ', '↪', 'hook right arrow'); +LatexCmds.searrow = bindVanillaSymbol('\\searrow ', '↘', 'southeast arrow'); +LatexCmds.leftharpoonup = bindVanillaSymbol('\\leftharpoonup ', '↼', 'left harpoon up'); +LatexCmds.rightharpoonup = bindVanillaSymbol('\\rightharpoonup ', '⇀', 'right harpoon up'); +LatexCmds.swarrow = bindVanillaSymbol('\\swarrow ', '↙', 'southwest arrow'); +LatexCmds.leftharpoondown = bindVanillaSymbol('\\leftharpoondown ', '↽', 'left harpoon down'); +LatexCmds.rightharpoondown = bindVanillaSymbol('\\rightharpoondown ', '⇁', 'right harpoon down'); +LatexCmds.nwarrow = bindVanillaSymbol('\\nwarrow ', '↖', 'northwest arrow'); //Misc -LatexCmds.ldots = bind(VanillaSymbol, '\\ldots ', '…', 'l dots'); -LatexCmds.cdots = bind(VanillaSymbol, '\\cdots ', '⋯', 'c dots'); -LatexCmds.vdots = bind(VanillaSymbol, '\\vdots ', '⋮', 'v dots'); -LatexCmds.ddots = bind(VanillaSymbol, '\\ddots ', '⋱', 'd dots'); -LatexCmds.surd = bind(VanillaSymbol, '\\surd ', '√', 'unresolved root'); -LatexCmds.triangle = bind(VanillaSymbol, '\\triangle ', '△', 'triangle'); -LatexCmds.ell = bind(VanillaSymbol, '\\ell ', 'ℓ', 'ell'); -LatexCmds.top = bind(VanillaSymbol, '\\top ', '⊤', 'top'); -LatexCmds.flat = bind(VanillaSymbol, '\\flat ', '♭', 'flat'); -LatexCmds.natural = bind(VanillaSymbol, '\\natural ', '♮', 'natural'); -LatexCmds.sharp = bind(VanillaSymbol, '\\sharp ', '♯', 'sharp'); -LatexCmds.wp = bind(VanillaSymbol, '\\wp ', '℘', 'wp'); -LatexCmds.bot = bind(VanillaSymbol, '\\bot ', '⊥', 'bot'); -LatexCmds.clubsuit = bind(VanillaSymbol, '\\clubsuit ', '♣', 'club suit'); -LatexCmds.diamondsuit = bind(VanillaSymbol, '\\diamondsuit ', '♢', 'diamond suit'); -LatexCmds.heartsuit = bind(VanillaSymbol, '\\heartsuit ', '♡', 'heart suit'); -LatexCmds.spadesuit = bind(VanillaSymbol, '\\spadesuit ', '♠', 'spade suit'); +LatexCmds.ldots = bindVanillaSymbol('\\ldots ', '…', 'l dots'); +LatexCmds.cdots = bindVanillaSymbol('\\cdots ', '⋯', 'c dots'); +LatexCmds.vdots = bindVanillaSymbol('\\vdots ', '⋮', 'v dots'); +LatexCmds.ddots = bindVanillaSymbol('\\ddots ', '⋱', 'd dots'); +LatexCmds.surd = bindVanillaSymbol('\\surd ', '√', 'unresolved root'); +LatexCmds.triangle = bindVanillaSymbol('\\triangle ', '△', 'triangle'); +LatexCmds.ell = bindVanillaSymbol('\\ell ', 'ℓ', 'ell'); +LatexCmds.top = bindVanillaSymbol('\\top ', '⊤', 'top'); +LatexCmds.flat = bindVanillaSymbol('\\flat ', '♭', 'flat'); +LatexCmds.natural = bindVanillaSymbol('\\natural ', '♮', 'natural'); +LatexCmds.sharp = bindVanillaSymbol('\\sharp ', '♯', 'sharp'); +LatexCmds.wp = bindVanillaSymbol('\\wp ', '℘', 'wp'); +LatexCmds.bot = bindVanillaSymbol('\\bot ', '⊥', 'bot'); +LatexCmds.clubsuit = bindVanillaSymbol('\\clubsuit ', '♣', 'club suit'); +LatexCmds.diamondsuit = bindVanillaSymbol('\\diamondsuit ', '♢', 'diamond suit'); +LatexCmds.heartsuit = bindVanillaSymbol('\\heartsuit ', '♡', 'heart suit'); +LatexCmds.spadesuit = bindVanillaSymbol('\\spadesuit ', '♠', 'spade suit'); //not real LaTex command see https://github.com/mathquill/mathquill/pull/552 for more details -LatexCmds.parallelogram = bind(VanillaSymbol, '\\parallelogram ', '▱', 'parallelogram'); -LatexCmds.square = bind(VanillaSymbol, '\\square ', '⬜', 'square'); +LatexCmds.parallelogram = bindVanillaSymbol('\\parallelogram ', '▱', 'parallelogram'); +LatexCmds.square = bindVanillaSymbol('\\square ', '⬜', 'square'); //variable-sized -LatexCmds.oint = bind(VanillaSymbol, '\\oint ', '∮', 'o int'); -LatexCmds.bigcap = bind(VanillaSymbol, '\\bigcap ', '∩', 'big cap'); -LatexCmds.bigcup = bind(VanillaSymbol, '\\bigcup ', '∪', 'big cup'); -LatexCmds.bigsqcup = bind(VanillaSymbol, '\\bigsqcup ', '⊔', 'big square cup'); -LatexCmds.bigvee = bind(VanillaSymbol, '\\bigvee ', '∨', 'big vee'); -LatexCmds.bigwedge = bind(VanillaSymbol, '\\bigwedge ', '∧', 'big wedge'); -LatexCmds.bigodot = bind(VanillaSymbol, '\\bigodot ', '⊙', 'big o dot'); -LatexCmds.bigotimes = bind(VanillaSymbol, '\\bigotimes ', '⊗', 'big o times'); -LatexCmds.bigoplus = bind(VanillaSymbol, '\\bigoplus ', '⊕', 'big o plus'); -LatexCmds.biguplus = bind(VanillaSymbol, '\\biguplus ', '⊎', 'big u plus'); +LatexCmds.oint = bindVanillaSymbol('\\oint ', '∮', 'o int'); +LatexCmds.bigcap = bindVanillaSymbol('\\bigcap ', '∩', 'big cap'); +LatexCmds.bigcup = bindVanillaSymbol('\\bigcup ', '∪', 'big cup'); +LatexCmds.bigsqcup = bindVanillaSymbol('\\bigsqcup ', '⊔', 'big square cup'); +LatexCmds.bigvee = bindVanillaSymbol('\\bigvee ', '∨', 'big vee'); +LatexCmds.bigwedge = bindVanillaSymbol('\\bigwedge ', '∧', 'big wedge'); +LatexCmds.bigodot = bindVanillaSymbol('\\bigodot ', '⊙', 'big o dot'); +LatexCmds.bigotimes = bindVanillaSymbol('\\bigotimes ', '⊗', 'big o times'); +LatexCmds.bigoplus = bindVanillaSymbol('\\bigoplus ', '⊕', 'big o plus'); +LatexCmds.biguplus = bindVanillaSymbol('\\biguplus ', '⊎', 'big u plus'); //delimiters -LatexCmds.lfloor = bind(VanillaSymbol, '\\lfloor ', '⌊', 'left floor'); -LatexCmds.rfloor = bind(VanillaSymbol, '\\rfloor ', '⌋', 'right floor'); -LatexCmds.lceil = bind(VanillaSymbol, '\\lceil ', '⌈', 'left ceiling'); -LatexCmds.rceil = bind(VanillaSymbol, '\\rceil ', '⌉', 'right ceiling'); -LatexCmds.opencurlybrace = LatexCmds.lbrace = bind(VanillaSymbol, '\\lbrace ', '{', 'left brace'); -LatexCmds.closecurlybrace = LatexCmds.rbrace = bind(VanillaSymbol, '\\rbrace ', '}', 'right brace'); -LatexCmds.lbrack = bind(VanillaSymbol, '[', 'left bracket'); -LatexCmds.rbrack = bind(VanillaSymbol, ']', 'right bracket'); +LatexCmds.lfloor = bindVanillaSymbol('\\lfloor ', '⌊', 'left floor'); +LatexCmds.rfloor = bindVanillaSymbol('\\rfloor ', '⌋', 'right floor'); +LatexCmds.lceil = bindVanillaSymbol('\\lceil ', '⌈', 'left ceiling'); +LatexCmds.rceil = bindVanillaSymbol('\\rceil ', '⌉', 'right ceiling'); +LatexCmds.opencurlybrace = LatexCmds.lbrace = bindVanillaSymbol('\\lbrace ', '{', 'left brace'); +LatexCmds.closecurlybrace = LatexCmds.rbrace = bindVanillaSymbol('\\rbrace ', '}', 'right brace'); +LatexCmds.lbrack = bindVanillaSymbol('[', 'left bracket'); +LatexCmds.rbrack = bindVanillaSymbol(']', 'right bracket'); //various symbols -LatexCmds.slash = bind(VanillaSymbol, '/', 'slash'); -LatexCmds.vert = bind(VanillaSymbol,'|', 'vertical bar'); -LatexCmds.perp = LatexCmds.perpendicular = bind(VanillaSymbol,'\\perp ','⊥', 'perpendicular'); -LatexCmds.nabla = LatexCmds.del = bind(VanillaSymbol,'\\nabla ','∇'); -LatexCmds.hbar = bind(VanillaSymbol,'\\hbar ','ℏ', 'horizontal bar'); +LatexCmds.slash = bindVanillaSymbol('/', 'slash'); +LatexCmds.vert = bindVanillaSymbol('|', 'vertical bar'); +LatexCmds.perp = LatexCmds.perpendicular = bindVanillaSymbol('\\perp ','⊥', 'perpendicular'); +LatexCmds.nabla = LatexCmds.del = bindVanillaSymbol('\\nabla ','∇'); +LatexCmds.hbar = bindVanillaSymbol('\\hbar ','ℏ', 'horizontal bar'); LatexCmds.AA = LatexCmds.Angstrom = LatexCmds.angstrom = - bind(VanillaSymbol,'\\text\\AA ','Å', 'AA'); + bindVanillaSymbol('\\text\\AA ','Å', 'AA'); LatexCmds.ring = LatexCmds.circ = LatexCmds.circle = - bind(VanillaSymbol,'\\circ ','∘', 'circle'); + bindVanillaSymbol('\\circ ','∘', 'circle'); -LatexCmds.bull = LatexCmds.bullet = bind(VanillaSymbol,'\\bullet ','•', 'bullet'); +LatexCmds.bull = LatexCmds.bullet = bindVanillaSymbol('\\bullet ','•', 'bullet'); LatexCmds.setminus = LatexCmds.smallsetminus = - bind(VanillaSymbol,'\\setminus ','∖', 'set minus'); + bindVanillaSymbol('\\setminus ','∖', 'set minus'); LatexCmds.not = //bind(Symbol,'\\not ','/', 'not'); -LatexCmds['¬'] = LatexCmds.neg = bind(VanillaSymbol,'\\neg ','¬', 'not'); +LatexCmds['¬'] = LatexCmds.neg = bindVanillaSymbol('\\neg ','¬', 'not'); LatexCmds['…'] = LatexCmds.dots = LatexCmds.ellip = LatexCmds.hellip = LatexCmds.ellipsis = LatexCmds.hellipsis = - bind(VanillaSymbol,'\\dots ','…', 'ellipsis'); + bindVanillaSymbol('\\dots ','…', 'ellipsis'); LatexCmds.converges = LatexCmds.darr = LatexCmds.dnarr = LatexCmds.dnarrow = LatexCmds.downarrow = - bind(VanillaSymbol,'\\downarrow ','↓', 'converges with'); + bindVanillaSymbol('\\downarrow ','↓', 'converges with'); LatexCmds.dArr = LatexCmds.dnArr = LatexCmds.dnArrow = LatexCmds.Downarrow = - bind(VanillaSymbol,'\\Downarrow ','⇓', 'down arrow'); + bindVanillaSymbol('\\Downarrow ','⇓', 'down arrow'); LatexCmds.diverges = LatexCmds.uarr = LatexCmds.uparrow = - bind(VanillaSymbol,'\\uparrow ','↑', 'diverges from'); + bindVanillaSymbol('\\uparrow ','↑', 'diverges from'); -LatexCmds.uArr = LatexCmds.Uparrow = bind(VanillaSymbol,'\\Uparrow ','⇑', 'up arrow'); +LatexCmds.uArr = LatexCmds.Uparrow = bindVanillaSymbol('\\Uparrow ','⇑', 'up arrow'); -LatexCmds.rarr = LatexCmds.rightarrow = bind(VanillaSymbol,'\\rightarrow ','→', 'right arrow'); +LatexCmds.rarr = LatexCmds.rightarrow = bindVanillaSymbol('\\rightarrow ','→', 'right arrow'); LatexCmds.implies = bind(BinaryOperator,'\\Rightarrow ','⇒', 'implies'); -LatexCmds.rArr = LatexCmds.Rightarrow = bind(VanillaSymbol,'\\Rightarrow ','⇒', 'right arrow'); +LatexCmds.rArr = LatexCmds.Rightarrow = bindVanillaSymbol('\\Rightarrow ','⇒', 'right arrow'); LatexCmds.gets = bind(BinaryOperator,'\\gets ','←', 'gets'); -LatexCmds.larr = LatexCmds.leftarrow = bind(VanillaSymbol,'\\leftarrow ','←', 'left arrow'); +LatexCmds.larr = LatexCmds.leftarrow = bindVanillaSymbol('\\leftarrow ','←', 'left arrow'); LatexCmds.impliedby = bind(BinaryOperator,'\\Leftarrow ','⇐', 'implied by'); -LatexCmds.lArr = LatexCmds.Leftarrow = bind(VanillaSymbol,'\\Leftarrow ','⇐', 'left arrow'); +LatexCmds.lArr = LatexCmds.Leftarrow = bindVanillaSymbol('\\Leftarrow ','⇐', 'left arrow'); LatexCmds.harr = LatexCmds.lrarr = LatexCmds.leftrightarrow = - bind(VanillaSymbol,'\\leftrightarrow ','↔', 'left and right arrow'); + bindVanillaSymbol('\\leftrightarrow ','↔', 'left and right arrow'); LatexCmds.iff = bind(BinaryOperator,'\\Leftrightarrow ','⇔', 'if and only if'); LatexCmds.hArr = LatexCmds.lrArr = LatexCmds.Leftrightarrow = - bind(VanillaSymbol,'\\Leftrightarrow ','⇔', 'left and right arrow'); + bindVanillaSymbol('\\Leftrightarrow ','⇔', 'left and right arrow'); -LatexCmds.Re = LatexCmds.Real = LatexCmds.real = bind(VanillaSymbol,'\\Re ','ℜ', 'real'); +LatexCmds.Re = LatexCmds.Real = LatexCmds.real = bindVanillaSymbol('\\Re ','ℜ', 'real'); LatexCmds.Im = LatexCmds.imag = LatexCmds.image = LatexCmds.imagin = LatexCmds.imaginary = LatexCmds.Imaginary = - bind(VanillaSymbol,'\\Im ','ℑ', 'imaginary'); + bindVanillaSymbol('\\Im ','ℑ', 'imaginary'); -LatexCmds.part = LatexCmds.partial = bind(VanillaSymbol,'\\partial ','∂', 'partial'); +LatexCmds.part = LatexCmds.partial = bindVanillaSymbol('\\partial ','∂', 'partial'); -LatexCmds.pounds = bind(VanillaSymbol,'\\pounds ','£'); +LatexCmds.pounds = bindVanillaSymbol('\\pounds ','£'); LatexCmds.alef = LatexCmds.alefsym = LatexCmds.aleph = LatexCmds.alephsym = - bind(VanillaSymbol,'\\aleph ','ℵ', 'alef sym'); + bindVanillaSymbol('\\aleph ','ℵ', 'alef sym'); LatexCmds.xist = //LOL LatexCmds.xists = LatexCmds.exist = LatexCmds.exists = - bind(VanillaSymbol,'\\exists ','∃', 'there exists at least 1'); + bindVanillaSymbol('\\exists ','∃', 'there exists at least 1'); LatexCmds.nexists = LatexCmds.nexist = - bind(VanillaSymbol, '\\nexists ', '∄', 'there is no'); + bindVanillaSymbol('\\nexists ', '∄', 'there is no'); LatexCmds.and = LatexCmds.land = LatexCmds.wedge = bind(BinaryOperator,'\\wedge ','∧', 'and'); @@ -332,7 +332,7 @@ LatexCmds.cap = LatexCmds.intersect = LatexCmds.intersection = bind(BinaryOperator,'\\cap ','∩', 'intersection'); // FIXME: the correct LaTeX would be ^\circ but we can't parse that -LatexCmds.deg = LatexCmds.degree = bind(VanillaSymbol,'\\degree ','°', 'degrees'); +LatexCmds.deg = LatexCmds.degree = bindVanillaSymbol('\\degree ','°', 'degrees'); -LatexCmds.ang = LatexCmds.angle = bind(VanillaSymbol,'\\angle ','∠', 'angle'); -LatexCmds.measuredangle = bind(VanillaSymbol,'\\measuredangle ','∡', 'measured angle'); +LatexCmds.ang = LatexCmds.angle = bindVanillaSymbol('\\angle ','∠', 'angle'); +LatexCmds.measuredangle = bindVanillaSymbol('\\measuredangle ','∡', 'measured angle'); diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index fafa55db5..316b133ae 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -554,16 +554,16 @@ LatexCmds['.'] = P(DigitGroupingChar, function(_, super_) { }; }); -LatexCmds["'"] = LatexCmds.prime = bind(VanillaSymbol, "'", '′', 'prime'); -LatexCmds['″'] = LatexCmds.dprime = bind(VanillaSymbol, '″', '″', 'double prime'); +LatexCmds["'"] = LatexCmds.prime = bindVanillaSymbol("'", '′', 'prime'); +LatexCmds['″'] = LatexCmds.dprime = bindVanillaSymbol('″', '″', 'double prime'); -LatexCmds.backslash = bind(VanillaSymbol,'\\backslash ','\\', 'backslash'); +LatexCmds.backslash = bindVanillaSymbol('\\backslash ','\\', 'backslash'); if (!CharCmds['\\']) CharCmds['\\'] = LatexCmds.backslash; -LatexCmds.$ = bind(VanillaSymbol, '\\$', '$', 'dollar'); +LatexCmds.$ = bindVanillaSymbol('\\$', '$', 'dollar'); -LatexCmds.square = bind(VanillaSymbol, '\\square ', '\u25A1', 'square'); -LatexCmds.mid = bind(VanillaSymbol, '\\mid ', '\u2223', 'mid'); +LatexCmds.square = bindVanillaSymbol('\\square ', '\u25A1', 'square'); +LatexCmds.mid = bindVanillaSymbol('\\mid ', '\u2223', 'mid'); // does not use Symbola font var NonSymbolaSymbol = P(Symbol, function(_, super_) { @@ -596,13 +596,13 @@ LatexCmds['%'] = P(NonSymbolaSymbol, function(_, super_) { }); LatexCmds['∥'] = LatexCmds.parallel = - bind(VanillaSymbol, '\\parallel ', '∥', 'parallel'); + bindVanillaSymbol('\\parallel ', '∥', 'parallel'); LatexCmds['∦'] = LatexCmds.nparallel = - bind(VanillaSymbol, '\\nparallel ', '∦', 'not parallel'); + bindVanillaSymbol('\\nparallel ', '∦', 'not parallel'); LatexCmds['⟂'] = LatexCmds.perp = - bind(VanillaSymbol, '\\perp ', '⟂', 'perpendicular'); + bindVanillaSymbol('\\perp ', '⟂', 'perpendicular'); //the following are all Greek to me, but this helped a lot: http://www.ams.org/STIX/ion/stixsig03.html @@ -924,7 +924,7 @@ LatexCmds['>'] = LatexCmds.gt = Greater; LatexCmds['≤'] = LatexCmds.le = LatexCmds.leq = bind(Inequality, less, false); LatexCmds['≥'] = LatexCmds.ge = LatexCmds.geq = bind(Inequality, greater, false); LatexCmds.infty = LatexCmds.infin = LatexCmds.infinity = - bind(VanillaSymbol,'\\infty ','∞', 'infinity'); + bindVanillaSymbol('\\infty ','∞', 'infinity'); LatexCmds['≠'] = LatexCmds.ne = LatexCmds.neq = bind(BinaryOperator,'\\ne ','≠', 'not equal'); var Equality = P(BinaryOperator, function(_, super_) { diff --git a/src/commands/text.js b/src/commands/text.js index ece3d1c25..d49b068ee 100644 --- a/src/commands/text.js +++ b/src/commands/text.js @@ -120,7 +120,7 @@ var TextBlock = P(Node, function(_, super_) { } else if (this.isEmpty()) { cursor.insRightOf(this); - VanillaSymbol('\\$','$').createLeftOf(cursor); + new VanillaSymbol('\\$','$').createLeftOf(cursor); } else if (!cursor[R]) cursor.insRightOf(this); else if (!cursor[L]) cursor.insLeftOf(this); @@ -378,7 +378,7 @@ var RootMathCommand = P(MathCommand, function(_, super_) { else if (this.isEmpty()) { cursor.insRightOf(this.parent); this.parent.deleteTowards(dir, cursor); - VanillaSymbol('\\$','$').createLeftOf(cursor.show()); + new VanillaSymbol('\\$','$').createLeftOf(cursor.show()); } else if (!cursor[R]) cursor.insRightOf(this.parent); @@ -406,7 +406,7 @@ var RootTextBlock = P(RootMathBlock, function(_, super_) { var html; if (ch === '<') html = '<'; else if (ch === '>') html = '>'; - VanillaSymbol(ch, html).createLeftOf(cursor); + new VanillaSymbol(ch, html).createLeftOf(cursor); } }; }); diff --git a/src/services/latex.js b/src/services/latex.js index 432c93261..554c8eb2b 100644 --- a/src/services/latex.js +++ b/src/services/latex.js @@ -28,7 +28,7 @@ var latexMathParser = (function() { // (either way, something that can be adopted by a MathBlock) var variable = letter.map(function(c) { return Letter(c); }); var number = digit.map(function (c) { return Digit(c); }); - var symbol = regex(/^[^${}\\_^]/).map(function(c) { return VanillaSymbol(c); }); + var symbol = regex(/^[^${}\\_^]/).map(function(c) { return new VanillaSymbol(c); }); var controlSequence = regex(/^[^\\a-eg-zA-Z]/) // hotfix #164; match MathBlock::write @@ -324,7 +324,7 @@ Controller.open(function(_, super_) { ; var escapedDollar = string('\\$').result('$'); - var textChar = escapedDollar.or(regex(/^[^$]/)).map(VanillaSymbol); + var textChar = escapedDollar.or(regex(/^[^$]/)).map((ch) => new VanillaSymbol(ch)); var latexText = mathMode.or(textChar).many(); var commands = latexText.skip(eof).or(all.result(false)).parse(latex); From be4ef876a46d108e9f83830ea4d02e1e06221073 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 14:15:58 -0500 Subject: [PATCH 010/192] convert BinaryOperator to ES6 class --- src/commands/math.js | 17 ++++++---- src/commands/math/advancedSymbols.js | 50 ++++++++++++++-------------- src/commands/math/basicSymbols.js | 8 ++--- 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/commands/math.js b/src/commands/math.js index fa410c971..1d752254b 100644 --- a/src/commands/math.js +++ b/src/commands/math.js @@ -406,13 +406,18 @@ function bindVanillaSymbol (ch, html, mathspeak) { return () => new VanillaSymbol(ch, html, mathspeak); } -var BinaryOperator = P(Symbol, function(_, super_) { - _.init = function(ctrlSeq, html, text, mathspeak) { - super_.init.call(this, - ctrlSeq, ''+html+'', text, mathspeak - ); +class BinaryOperator extends Symbol { + constructor (ctrlSeq, html, text, mathspeak) { + super(); + this.init(ctrlSeq, html, text, mathspeak); + } + init (ctrlSeq, html, text, mathspeak) { + super.init(ctrlSeq, ''+html+'', text, mathspeak); }; -}); +}; +function bindBinaryOperator (ctrlSeq, html, text, mathspeak) { + return () => new BinaryOperator(ctrlSeq, html, text, mathspeak); +} /** * Children and parent of MathCommand's. Basically partitions all the diff --git a/src/commands/math/advancedSymbols.js b/src/commands/math/advancedSymbols.js index 9f3f4fcef..7b66f2d7c 100644 --- a/src/commands/math/advancedSymbols.js +++ b/src/commands/math/advancedSymbols.js @@ -13,51 +13,51 @@ LatexCmds.otimes = P(BinaryOperator, function(_, super_) { }); LatexCmds['∗'] = LatexCmds.ast = LatexCmds.star = LatexCmds.loast = LatexCmds.lowast = - bind(BinaryOperator,'\\ast ','∗', 'low asterisk'); + bindBinaryOperator('\\ast ','∗', 'low asterisk'); LatexCmds.therefor = LatexCmds.therefore = - bind(BinaryOperator,'\\therefore ','∴', 'therefore'); + bindBinaryOperator('\\therefore ','∴', 'therefore'); LatexCmds.cuz = // l33t -LatexCmds.because = bind(BinaryOperator,'\\because ','∵', 'because'); +LatexCmds.because = bindBinaryOperator('\\because ','∵', 'because'); -LatexCmds.prop = LatexCmds.propto = bind(BinaryOperator,'\\propto ','∝', 'proportional to'); +LatexCmds.prop = LatexCmds.propto = bindBinaryOperator('\\propto ','∝', 'proportional to'); -LatexCmds['≈'] = LatexCmds.asymp = LatexCmds.approx = bind(BinaryOperator,'\\approx ','≈'), 'approximately equal to'; +LatexCmds['≈'] = LatexCmds.asymp = LatexCmds.approx = bindBinaryOperator('\\approx ','≈', 'approximately equal to'); -LatexCmds.isin = LatexCmds['in'] = bind(BinaryOperator,'\\in ','∈', 'is in'); +LatexCmds.isin = LatexCmds['in'] = bindBinaryOperator('\\in ','∈', 'is in'); -LatexCmds.ni = LatexCmds.contains = bind(BinaryOperator,'\\ni ','∋', 'is not in'); +LatexCmds.ni = LatexCmds.contains = bindBinaryOperator('\\ni ','∋', 'is not in'); LatexCmds.notni = LatexCmds.niton = LatexCmds.notcontains = LatexCmds.doesnotcontain = - bind(BinaryOperator,'\\not\\ni ','∌', 'does not contain'); + bindBinaryOperator('\\not\\ni ','∌', 'does not contain'); -LatexCmds.sub = LatexCmds.subset = bind(BinaryOperator,'\\subset ','⊂', 'subset'); +LatexCmds.sub = LatexCmds.subset = bindBinaryOperator('\\subset ','⊂', 'subset'); LatexCmds.sup = LatexCmds.supset = LatexCmds.superset = - bind(BinaryOperator,'\\supset ','⊃', 'superset'); + bindBinaryOperator('\\supset ','⊃', 'superset'); LatexCmds.nsub = LatexCmds.notsub = LatexCmds.nsubset = LatexCmds.notsubset = - bind(BinaryOperator,'\\not\\subset ','⊄', 'not a subset'); + bindBinaryOperator('\\not\\subset ','⊄', 'not a subset'); LatexCmds.nsup = LatexCmds.notsup = LatexCmds.nsupset = LatexCmds.notsupset = LatexCmds.nsuperset = LatexCmds.notsuperset = - bind(BinaryOperator,'\\not\\supset ','⊅', 'not a superset'); + bindBinaryOperator('\\not\\supset ','⊅', 'not a superset'); LatexCmds.sube = LatexCmds.subeq = LatexCmds.subsete = LatexCmds.subseteq = - bind(BinaryOperator,'\\subseteq ','⊆', 'subset or equal to'); + bindBinaryOperator('\\subseteq ','⊆', 'subset or equal to'); LatexCmds.supe = LatexCmds.supeq = LatexCmds.supsete = LatexCmds.supseteq = LatexCmds.supersete = LatexCmds.superseteq = - bind(BinaryOperator,'\\supseteq ','⊇', 'superset or equal to'); + bindBinaryOperator('\\supseteq ','⊇', 'superset or equal to'); LatexCmds.nsube = LatexCmds.nsubeq = LatexCmds.notsube = LatexCmds.notsubeq = LatexCmds.nsubsete = LatexCmds.nsubseteq = LatexCmds.notsubsete = LatexCmds.notsubseteq = - bind(BinaryOperator,'\\not\\subseteq ','⊈', 'not subset or equal to'); + bindBinaryOperator('\\not\\subseteq ','⊈', 'not subset or equal to'); LatexCmds.nsupe = LatexCmds.nsupeq = LatexCmds.notsupe = LatexCmds.notsupeq = @@ -65,7 +65,7 @@ LatexCmds.nsupsete = LatexCmds.nsupseteq = LatexCmds.notsupsete = LatexCmds.notsupseteq = LatexCmds.nsupersete = LatexCmds.nsuperseteq = LatexCmds.notsupersete = LatexCmds.notsuperseteq = - bind(BinaryOperator,'\\not\\supseteq ','⊉', 'not superset or equal to'); + bindBinaryOperator('\\not\\supseteq ','⊉', 'not superset or equal to'); //the canonical sets of numbers LatexCmds.mathbb = P(MathCommand, function(_) { @@ -275,22 +275,22 @@ LatexCmds.uArr = LatexCmds.Uparrow = bindVanillaSymbol('\\Uparrow ','⇑', 'u LatexCmds.rarr = LatexCmds.rightarrow = bindVanillaSymbol('\\rightarrow ','→', 'right arrow'); -LatexCmds.implies = bind(BinaryOperator,'\\Rightarrow ','⇒', 'implies'); +LatexCmds.implies = bindBinaryOperator('\\Rightarrow ','⇒', 'implies'); LatexCmds.rArr = LatexCmds.Rightarrow = bindVanillaSymbol('\\Rightarrow ','⇒', 'right arrow'); -LatexCmds.gets = bind(BinaryOperator,'\\gets ','←', 'gets'); +LatexCmds.gets = bindBinaryOperator('\\gets ','←', 'gets'); LatexCmds.larr = LatexCmds.leftarrow = bindVanillaSymbol('\\leftarrow ','←', 'left arrow'); -LatexCmds.impliedby = bind(BinaryOperator,'\\Leftarrow ','⇐', 'implied by'); +LatexCmds.impliedby = bindBinaryOperator('\\Leftarrow ','⇐', 'implied by'); LatexCmds.lArr = LatexCmds.Leftarrow = bindVanillaSymbol('\\Leftarrow ','⇐', 'left arrow'); LatexCmds.harr = LatexCmds.lrarr = LatexCmds.leftrightarrow = bindVanillaSymbol('\\leftrightarrow ','↔', 'left and right arrow'); -LatexCmds.iff = bind(BinaryOperator,'\\Leftrightarrow ','⇔', 'if and only if'); +LatexCmds.iff = bindBinaryOperator('\\Leftrightarrow ','⇔', 'if and only if'); LatexCmds.hArr = LatexCmds.lrArr = LatexCmds.Leftrightarrow = bindVanillaSymbol('\\Leftrightarrow ','⇔', 'left and right arrow'); @@ -316,20 +316,20 @@ LatexCmds.nexists = LatexCmds.nexist = bindVanillaSymbol('\\nexists ', '∄', 'there is no'); LatexCmds.and = LatexCmds.land = LatexCmds.wedge = - bind(BinaryOperator,'\\wedge ','∧', 'and'); + bindBinaryOperator('\\wedge ','∧', 'and'); -LatexCmds.or = LatexCmds.lor = LatexCmds.vee = bind(BinaryOperator,'\\vee ','∨', 'or'); +LatexCmds.or = LatexCmds.lor = LatexCmds.vee = bindBinaryOperator('\\vee ','∨', 'or'); LatexCmds.o = LatexCmds.O = LatexCmds.empty = LatexCmds.emptyset = LatexCmds.oslash = LatexCmds.Oslash = LatexCmds.nothing = LatexCmds.varnothing = - bind(BinaryOperator,'\\varnothing ','∅', 'nothing'); + bindBinaryOperator('\\varnothing ','∅', 'nothing'); -LatexCmds.cup = LatexCmds.union = bind(BinaryOperator,'\\cup ','∪', 'union'); +LatexCmds.cup = LatexCmds.union = bindBinaryOperator('\\cup ','∪', 'union'); LatexCmds.cap = LatexCmds.intersect = LatexCmds.intersection = - bind(BinaryOperator,'\\cap ','∩', 'intersection'); + bindBinaryOperator('\\cap ','∩', 'intersection'); // FIXME: the correct LaTeX would be ^\circ but we can't parse that LatexCmds.deg = LatexCmds.degree = bindVanillaSymbol('\\degree ','°', 'degrees'); diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 316b133ae..f98e82341 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -850,7 +850,7 @@ LatexCmds.mp = LatexCmds.mnplus = LatexCmds.minusplus = bind(PlusMinus,'\\mp ','∓', 'minus-or-plus'); CharCmds['*'] = LatexCmds.sdot = LatexCmds.cdot = - bind(BinaryOperator, '\\cdot ', '·', '*', 'times'); //semantically should be ⋅, but · looks better + bindBinaryOperator('\\cdot ', '·', '*', 'times'); //semantically should be ⋅, but · looks better var To = P(BinaryOperator, function(_, super_) { _.init = function() { @@ -925,7 +925,7 @@ LatexCmds['≤'] = LatexCmds.le = LatexCmds.leq = bind(Inequality, less, false); LatexCmds['≥'] = LatexCmds.ge = LatexCmds.geq = bind(Inequality, greater, false); LatexCmds.infty = LatexCmds.infin = LatexCmds.infinity = bindVanillaSymbol('\\infty ','∞', 'infinity'); -LatexCmds['≠'] = LatexCmds.ne = LatexCmds.neq = bind(BinaryOperator,'\\ne ','≠', 'not equal'); +LatexCmds['≠'] = LatexCmds.ne = LatexCmds.neq = bindBinaryOperator('\\ne ','≠', 'not equal'); var Equality = P(BinaryOperator, function(_, super_) { _.init = function() { @@ -942,10 +942,10 @@ var Equality = P(BinaryOperator, function(_, super_) { }); LatexCmds['='] = Equality; -LatexCmds['×'] = LatexCmds.times = bind(BinaryOperator, '\\times ', '×', '[x]', 'times'); +LatexCmds['×'] = LatexCmds.times = bindBinaryOperator('\\times ', '×', '[x]', 'times'); LatexCmds['÷'] = LatexCmds.div = LatexCmds.divide = LatexCmds.divides = - bind(BinaryOperator,'\\div ','÷', '[/]', 'over'); + bindBinaryOperator('\\div ','÷', '[/]', 'over'); var Sim = P(BinaryOperator, function(_, super_) { From bd890113248611689f93213a32be601560ab099c Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 14:31:56 -0500 Subject: [PATCH 011/192] convert MathBlock to ES6 class --- src/commands/math.js | 41 ++++++++++++++++--------------- src/commands/math/basicSymbols.js | 2 +- src/commands/math/commands.js | 4 +-- src/publicapi.js | 2 +- src/services/latex.js | 4 +-- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/commands/math.js b/src/commands/math.js index 1d752254b..f0484b158 100644 --- a/src/commands/math.js +++ b/src/commands/math.js @@ -133,7 +133,7 @@ class MathCommand extends MathElement { blocks = cmd.blocks = Array(numBlocks); for (var i = 0; i < numBlocks; i += 1) { - var newBlock = blocks[i] = MathBlock(); + var newBlock = blocks[i] = new MathBlock(); newBlock.adopt(cmd, cmd.ends[R], 0); } }; @@ -424,21 +424,21 @@ function bindBinaryOperator (ctrlSeq, html, text, mathspeak) { * symbols and operators that descend (in the Math DOM tree) from * ancestor operators. */ -var MathBlock = P(MathElement, function(_, super_) { - _.join = function(methodName) { +class MathBlock extends MathElement { + join (methodName) { return this.foldChildren('', function(fold, child) { return fold + child[methodName](); }); }; - _.html = function() { return this.join('html'); }; - _.latex = function() { return this.join('latex'); }; - _.text = function() { + html () { return this.join('html'); }; + latex () { return this.join('latex'); }; + text () { return (this.ends[L] === this.ends[R] && this.ends[L] !== 0) ? this.ends[L].text() : this.join('text') ; }; - _.mathspeak = function() { + mathspeak () { var tempOp = ''; var autoOps = {}; if (this.controller) autoOps = this.controller.options.autoOperatorNames; @@ -476,22 +476,23 @@ var MathBlock = P(MathElement, function(_, super_) { return p1 + p2.split('').join(' ').trim(); }); }; - _.ariaLabel = 'block'; - _.keystroke = function(key, e, ctrlr) { + static _todoMoveIntoConstructor = MathBlock.prototype.ariaLabel = 'block'; + + keystroke (key, e, ctrlr) { if (ctrlr.options.spaceBehavesLikeTab && (key === 'Spacebar' || key === 'Shift-Spacebar')) { e.preventDefault(); ctrlr.escapeDir(key === 'Shift-Spacebar' ? L : R, key, e); return; } - return super_.keystroke.apply(this, arguments); + return super.keystroke.apply(this, arguments); }; // editability methods: called by the cursor for editing, cursor movements, // and selection of the MathQuill tree, these all take in a direction and // the cursor - _.moveOutOf = function(dir, cursor, updown) { + moveOutOf (dir, cursor, updown) { var updownInto = updown && this.parent[updown+'Into']; if (!updownInto && this[dir]) { cursor.insAtDirEnd(-dir, this[dir]); @@ -502,13 +503,13 @@ var MathBlock = P(MathElement, function(_, super_) { aria.queueDirOf(dir).queue(this.parent); } }; - _.selectOutOf = function(dir, cursor) { + selectOutOf (dir, cursor) { cursor.insDirOf(dir, this.parent); }; - _.deleteOutOf = function(dir, cursor) { + deleteOutOf (dir, cursor) { cursor.unwrapGramp(); }; - _.seek = function(pageX, cursor) { + seek (pageX, cursor) { var node = this.ends[R]; if (!node || node.jQ.offset().left + node.jQ.outerWidth() < pageX) { return cursor.insAtRightEnd(this); @@ -517,7 +518,7 @@ var MathBlock = P(MathElement, function(_, super_) { while (pageX < node.jQ.offset().left) node = node[L]; return node.seek(pageX, cursor); }; - _.chToCmd = function(ch, options) { + chToCmd (ch, options) { var cons; // exclude f because it gets a dedicated command with more spacing if (ch.match(/^[a-eg-zA-Z]$/)) @@ -536,7 +537,7 @@ var MathBlock = P(MathElement, function(_, super_) { else return new VanillaSymbol(ch); }; - _.write = function(cursor, ch) { + write (cursor, ch) { var cmd = this.chToCmd(ch, cursor.options); if (cursor.selection) cmd.replaces(cursor.replaceSelection()); if (!cursor.isTooDeep()) { @@ -550,7 +551,7 @@ var MathBlock = P(MathElement, function(_, super_) { } }; - _.writeLatex = function(cursor, latex) { + writeLatex (cursor, latex) { var all = Parser.all; var eof = Parser.eof; @@ -569,13 +570,13 @@ var MathBlock = P(MathElement, function(_, super_) { } }; - _.focus = function() { + focus () { this.jQ.addClass('mq-hasCursor'); this.jQ.removeClass('mq-empty'); return this; }; - _.blur = function() { + blur () { this.jQ.removeClass('mq-hasCursor'); if (this.isEmpty()) { this.jQ.addClass('mq-empty'); @@ -587,7 +588,7 @@ var MathBlock = P(MathElement, function(_, super_) { } return this; }; -}); +} Options.p.mouseEvents = true; API.StaticMath = function(APIClasses) { diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index f98e82341..9288e0d91 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -497,7 +497,7 @@ var OperatorName = P(Symbol, function(_, super_) { }; _.parser = function() { var fn = this.ctrlSeq; - var block = MathBlock(); + var block = new MathBlock(); for (var i = 0; i < fn.length; i += 1) { Letter(fn.charAt(i)).adopt(block, block.ends[R], 0); } diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 3e5f9bc91..849dc311a 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -285,7 +285,7 @@ var SupSub = P(MathCommand, function(_, super_) { cursor.insRightOf(this.parent); aria.queue('Baseline'); } - MathBlock.p.write.apply(this, arguments); + MathBlock.prototype.write.apply(this, arguments); }; }; _.moveTowards = function(dir, cursor, updown) { @@ -496,7 +496,7 @@ var SummationNotation = P(MathCommand, function(_, super_) { var block = latexMathParser.block; var self = this; - var blocks = self.blocks = [ MathBlock(), MathBlock() ]; + var blocks = self.blocks = [ new MathBlock(), new MathBlock() ]; for (var i = 0; i < blocks.length; i += 1) { blocks[i].adopt(self, self.ends[R], 0); } diff --git a/src/publicapi.js b/src/publicapi.js index c3a2dab1a..9d5336b11 100644 --- a/src/publicapi.js +++ b/src/publicapi.js @@ -270,7 +270,7 @@ function getInterface(v) { MQ[kind] = function(el, opts) { var mq = MQ(el); if (mq instanceof APIClass || !el || !el.nodeType) return mq; - var ctrlr = Controller(APIClass.RootBlock(), $(el), Options()); + var ctrlr = Controller(new APIClass.RootBlock(), $(el), Options()); ctrlr.KIND_OF_MQ = kind; return APIClass(ctrlr).__mathquillify(opts, v); }; diff --git a/src/services/latex.js b/src/services/latex.js index 554c8eb2b..03cb47c40 100644 --- a/src/services/latex.js +++ b/src/services/latex.js @@ -1,12 +1,12 @@ // Parser MathBlock var latexMathParser = (function() { function commandToBlock(cmd) { // can also take in a Fragment - var block = MathBlock(); + var block = new MathBlock(); cmd.adopt(block, 0, 0); return block; } function joinBlocks(blocks) { - var firstBlock = blocks[0] || MathBlock(); + var firstBlock = blocks[0] || new MathBlock(); for (var i = 1; i < blocks.length; i += 1) { blocks[i].children().adopt(firstBlock, firstBlock.ends[R], 0); From d9093d7d9440cff1db2e76cfe2bb89a4b5d7ade2 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 14:58:52 -0500 Subject: [PATCH 012/192] convert TextBlock to ES6 class --- src/commands/math/LatexCommandInput.js | 2 +- src/commands/text.js | 105 ++++++++++++++----------- 2 files changed, 60 insertions(+), 47 deletions(-) diff --git a/src/commands/math/LatexCommandInput.js b/src/commands/math/LatexCommandInput.js index 188e20e23..6faa9bd62 100644 --- a/src/commands/math/LatexCommandInput.js +++ b/src/commands/math/LatexCommandInput.js @@ -90,7 +90,7 @@ CharCmds['\\'] = P(MathCommand, function(_, super_) { cmd.createLeftOf(cursor); } else { - cmd = TextBlock(); + cmd = new TextBlock(); cmd.replaces(latex); cmd.createLeftOf(cursor); cursor.insRightOf(cmd); diff --git a/src/commands/text.js b/src/commands/text.js index d49b068ee..222ac9de0 100644 --- a/src/commands/text.js +++ b/src/commands/text.js @@ -8,25 +8,27 @@ * opposed to hierchical, nested, tree-structured math. * Wraps a single HTMLSpanElement. */ -var TextBlock = P(Node, function(_, super_) { - _.ctrlSeq = '\\text'; - _.ariaLabel = 'Text'; +class TextBlock extends Node { + static _todoMoveIntoConstructor = + TextBlock.prototype.ctrlSeq = '\\text'; + static _todoMoveIntoConstructor = + TextBlock.prototype.ariaLabel = 'Text'; - _.replaces = function(replacedText) { + replaces (replacedText) { if (replacedText instanceof Fragment) this.replacedText = replacedText.remove().jQ.text(); else if (typeof replacedText === 'string') this.replacedText = replacedText; }; - _.jQadd = function(jQ) { - super_.jQadd.call(this, jQ); + jQadd (jQ) { + super.jQadd.call(this, jQ); if (this.ends[L]) this.ends[L].jQadd(this.jQ[0].firstChild); }; - _.createLeftOf = function(cursor) { + createLeftOf (cursor) { var textBlock = this; - super_.createLeftOf.call(this, cursor); + super.createLeftOf.call(this, cursor); cursor.insAtRightEnd(textBlock); @@ -39,7 +41,7 @@ var TextBlock = P(Node, function(_, super_) { textBlock.bubble(function (node) { node.reflow(); }); }; - _.parser = function() { + parser () { var textBlock = this; // TODO: correctly parse text mode @@ -57,61 +59,70 @@ var TextBlock = P(Node, function(_, super_) { ; }; - _.textContents = function() { + textContents () { return this.foldChildren('', function(text, child) { return text + child.text; }); }; - _.text = function() { return '"' + this.textContents() + '"'; }; - _.latex = function() { + text () { return '"' + this.textContents() + '"'; }; + latex () { var contents = this.textContents(); if (contents.length === 0) return ''; return this.ctrlSeq + '{' + contents.replace(/\\/g, '\\backslash ').replace(/[{}]/g, '\\$&') + '}'; }; - _.html = function() { + html () { return ( '' + this.textContents() + '' ); }; - _.mathspeakTemplate = ['Start'+_.ariaLabel, 'End'+_.ariaLabel]; - _.mathspeak = function(opts) { + + static _todoMoveIntoConstructor = + TextBlock.prototype.mathspeakTemplate = + ['Start'+TextBlock.prototype.ariaLabel, 'End'+TextBlock.prototype.ariaLabel]; + mathspeak (opts) { if (opts && opts.ignoreShorthand) { return this.mathspeakTemplate[0]+', '+this.textContents() +', '+this.mathspeakTemplate[1] } else { return this.textContents(); } }; - _.isTextBlock = function() { + isTextBlock () { return true; }; // editability methods: called by the cursor for editing, cursor movements, // and selection of the MathQuill tree, these all take in a direction and // the cursor - _.moveTowards = function(dir, cursor) { + moveTowards (dir, cursor) { cursor.insAtDirEnd(-dir, this); aria.queueDirEndOf(-dir).queue(cursor.parent, true); }; - _.moveOutOf = function(dir, cursor) { + moveOutOf (dir, cursor) { cursor.insDirOf(dir, this); aria.queueDirOf(dir).queue(this); }; - _.unselectInto = _.moveTowards; + unselectInto (dir,cursor) { + this.moveTowards(dir, cursor); + } // TODO: make these methods part of a shared mixin or something. - _.selectTowards = MathCommand.prototype.selectTowards; - _.deleteTowards = MathCommand.prototype.deleteTowards; + selectTowards (dir, cursor) { + MathCommand.prototype.selectTowards.call(this, dir, cursor); + } + deleteTowards (dir, cursor) { + MathCommand.prototype.deleteTowards.call(this, dir, cursor); + } - _.selectOutOf = function(dir, cursor) { + selectOutOf (dir, cursor) { cursor.insDirOf(dir, this); }; - _.deleteOutOf = function(dir, cursor) { + deleteOutOf (dir, cursor) { // backspace and delete at ends of block don't unwrap if (this.isEmpty()) cursor.insRightOf(this); }; - _.write = function(cursor, ch) { + write (cursor, ch) { cursor.show().deleteSelection(); if (ch !== '$') { @@ -125,27 +136,27 @@ var TextBlock = P(Node, function(_, super_) { else if (!cursor[R]) cursor.insRightOf(this); else if (!cursor[L]) cursor.insLeftOf(this); else { // split apart - var leftBlock = TextBlock(); + var leftBlock = new TextBlock(); var leftPc = this.ends[L]; leftPc.disown().jQ.detach(); leftPc.adopt(leftBlock, 0, 0); cursor.insLeftOf(this); - super_.createLeftOf.call(leftBlock, cursor); // micro-optimization, not for correctness + super.createLeftOf.call(leftBlock, cursor); // micro-optimization, not for correctness } this.bubble(function (node) { node.reflow(); }); // TODO needs tests aria.alert(ch); }; - _.writeLatex = function(cursor, latex) { + writeLatex (cursor, latex) { if (!cursor[L]) TextPiece(latex).createLeftOf(cursor); else cursor[L].appendText(latex); this.bubble(function (node) { node.reflow(); }); }; - _.seek = function(pageX, cursor) { + seek (pageX, cursor) { cursor.hide(); - var textPc = fuseChildren(this); + var textPc = TextBlockFuseChildren(this); // insert cursor at approx position in DOMTextNode var avgChWidth = this.jQ.width()/this.text.length; @@ -190,7 +201,7 @@ var TextBlock = P(Node, function(_, super_) { } }; - _.blur = function(cursor) { + blur (cursor) { MathBlock.prototype.blur.call(this); if (!cursor) return; if (this.textContents() === '') { @@ -198,27 +209,29 @@ var TextBlock = P(Node, function(_, super_) { if (cursor[L] === this) cursor[L] = this[L]; else if (cursor[R] === this) cursor[R] = this[R]; } - else fuseChildren(this); + else TextBlockFuseChildren(this); }; - function fuseChildren(self) { - self.jQ[0].normalize(); + focus () { + MathBlock.prototype.focus.call(this); + } +}; - var textPcDom = self.jQ[0].firstChild; - if (!textPcDom) return; - pray('only node in TextBlock span is Text node', textPcDom.nodeType === 3); - // nodeType === 3 has meant a Text node since ancient times: - // http://reference.sitepoint.com/javascript/Node/nodeType +function TextBlockFuseChildren(self) { + self.jQ[0].normalize(); - var textPc = TextPiece(textPcDom.data); - textPc.jQadd(textPcDom); + var textPcDom = self.jQ[0].firstChild; + if (!textPcDom) return; + pray('only node in TextBlock span is Text node', textPcDom.nodeType === 3); + // nodeType === 3 has meant a Text node since ancient times: + // http://reference.sitepoint.com/javascript/Node/nodeType - self.children().disown(); - return textPc.adopt(self, 0, 0); - } + var textPc = TextPiece(textPcDom.data); + textPc.jQadd(textPcDom); - _.focus = MathBlock.prototype.focus; -}); + self.children().disown(); + return textPc.adopt(self, 0, 0); +} /** * Piece of plain text, with a TextBlock as a parent and no children. @@ -331,7 +344,7 @@ LatexCmds.text = LatexCmds.textnormal = LatexCmds.textrm = LatexCmds.textup = -LatexCmds.textmd = TextBlock; +LatexCmds.textmd = P(TextBlock, {}); function makeTextBlock(latex, ariaLabel, tagName, attrs) { return P(TextBlock, { From 4d5dc93717efa8e455e9f620435ee58455e3e720 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 15:13:03 -0500 Subject: [PATCH 013/192] convert TextPiece to ES6 class --- src/commands/text.js | 57 ++++++++++++++++++++++++-------------------- src/tree.js | 5 ++++ 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/commands/text.js b/src/commands/text.js index 222ac9de0..137310c39 100644 --- a/src/commands/text.js +++ b/src/commands/text.js @@ -53,7 +53,7 @@ class TextBlock extends Node { .map(function(text) { if (text.length === 0) return new Fragment(); - TextPiece(text).adopt(textBlock, 0, 0); + new TextPiece(text).adopt(textBlock, 0, 0); return textBlock; }) ; @@ -126,7 +126,7 @@ class TextBlock extends Node { cursor.show().deleteSelection(); if (ch !== '$') { - if (!cursor[L]) TextPiece(ch).createLeftOf(cursor); + if (!cursor[L]) new TextPiece(ch).createLeftOf(cursor); else cursor[L].appendText(ch); } else if (this.isEmpty()) { @@ -149,7 +149,7 @@ class TextBlock extends Node { aria.alert(ch); }; writeLatex (cursor, latex) { - if (!cursor[L]) TextPiece(latex).createLeftOf(cursor); + if (!cursor[L]) new TextPiece(latex).createLeftOf(cursor); else cursor[L].appendText(latex); this.bubble(function (node) { node.reflow(); }); }; @@ -226,7 +226,7 @@ function TextBlockFuseChildren(self) { // nodeType === 3 has meant a Text node since ancient times: // http://reference.sitepoint.com/javascript/Node/nodeType - var textPc = TextPiece(textPcDom.data); + var textPc = new TextPiece(textPcDom.data); textPc.jQadd(textPcDom); self.children().disown(); @@ -240,54 +240,59 @@ function TextBlockFuseChildren(self) { * mirroring the text contents of the DOMTextNode. * Text contents must always be nonempty. */ -var TextPiece = P(Node, function(_, super_) { - _.init = function(text) { - super_.init.call(this); +class TextPiece extends Node { + constructor (text) { + super(); + this.init(text); + } + + init (text) { + super.init.call(this); this.text = text; }; - _.jQadd = function(dom) { this.dom = dom; this.jQ = $(dom); }; - _.jQize = function() { + jQadd (dom) { this.dom = dom; this.jQ = $(dom); }; + jQize () { return this.jQadd(document.createTextNode(this.text)); }; - _.appendText = function(text) { + appendText (text) { this.text += text; this.dom.appendData(text); }; - _.prependText = function(text) { + prependText (text) { this.text = text + this.text; this.dom.insertData(0, text); }; - _.insTextAtDirEnd = function(text, dir) { + insTextAtDirEnd (text, dir) { prayDirection(dir); if (dir === R) this.appendText(text); else this.prependText(text); }; - _.splitRight = function(i) { - var newPc = TextPiece(this.text.slice(i)).adopt(this.parent, this, this[R]); + splitRight (i) { + var newPc = new TextPiece(this.text.slice(i)).adopt(this.parent, this, this[R]); newPc.jQadd(this.dom.splitText(i)); this.text = this.text.slice(0, i); return newPc; }; - function endChar(dir, text) { + endChar(dir, text) { return text.charAt(dir === L ? 0 : -1 + text.length); } - _.moveTowards = function(dir, cursor) { + moveTowards (dir, cursor) { prayDirection(dir); - var ch = endChar(-dir, this.text) + var ch = this.endChar(-dir, this.text) var from = this[-dir]; if (from) from.insTextAtDirEnd(ch, dir); - else TextPiece(ch).createDir(-dir, cursor); + else new TextPiece(ch).createDir(-dir, cursor); return this.deleteTowards(dir, cursor); }; - _.mathspeak = - _.latex = function() { return this.text; }; + mathspeak () { return this.text; }; + latex () { return this.text; }; - _.deleteTowards = function(dir, cursor) { + deleteTowards (dir, cursor) { if (this.text.length > 1) { var deletedChar; if (dir === R) { @@ -312,14 +317,14 @@ var TextPiece = P(Node, function(_, super_) { } }; - _.selectTowards = function(dir, cursor) { + selectTowards (dir, cursor) { prayDirection(dir); var anticursor = cursor.anticursor; - var ch = endChar(-dir, this.text) + var ch = this.endChar(-dir, this.text) if (anticursor[dir] === this) { - var newPc = TextPiece(ch).createDir(dir, cursor); + var newPc = new TextPiece(ch).createDir(dir, cursor); anticursor[dir] = newPc; cursor.insDirOf(dir, newPc); } @@ -327,7 +332,7 @@ var TextPiece = P(Node, function(_, super_) { var from = this[-dir]; if (from) from.insTextAtDirEnd(ch, dir); else { - var newPc = TextPiece(ch).createDir(-dir, cursor); + var newPc = new TextPiece(ch).createDir(-dir, cursor); newPc.jQ.insDirOf(-dir, cursor.selection.jQ); } @@ -338,7 +343,7 @@ var TextPiece = P(Node, function(_, super_) { return this.deleteTowards(dir, cursor); }; -}); +}; LatexCmds.text = LatexCmds.textnormal = diff --git a/src/tree.js b/src/tree.js index 950319d02..372d7fbbd 100644 --- a/src/tree.js +++ b/src/tree.js @@ -178,6 +178,11 @@ class NodeBase { // any extensions that define an init method can call // this version instead of completely overwriting it init () { + // it's possible for this to get called multiple times + // during the transitionary period from PJS to Typescript. + // don't do anything the second time. + if (this.id !== undefined) return; + this[L] = 0; this[R] = 0 this.parent = 0; From 3ca5272c868791d29d85319f12ebe9afcc71e536 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 15:16:13 -0500 Subject: [PATCH 014/192] convert RootMathCommand to ES6 class --- src/commands/text.js | 24 +++++++++++++++--------- src/services/latex.js | 2 +- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/commands/text.js b/src/commands/text.js index 137310c39..f5373d16f 100644 --- a/src/commands/text.js +++ b/src/commands/text.js @@ -245,7 +245,7 @@ class TextPiece extends Node { super(); this.init(text); } - + init (text) { super.init.call(this); this.text = text; @@ -380,14 +380,20 @@ LatexCmds.lowercase = makeTextBlock('\\lowercase', 'Lowercase', 'span', 'style="text-transform:lowercase" class="mq-text-mode"'); -var RootMathCommand = P(MathCommand, function(_, super_) { - _.init = function(cursor) { - super_.init.call(this, '$'); +class RootMathCommand extends MathCommand { + constructor (cursor) { + super(); + this.init(cursor); + } + + init (cursor) { + super.init.call(this, '$'); this.cursor = cursor; }; - _.htmlTemplate = '&0'; - _.createBlocks = function() { - super_.createBlocks.call(this); + static _todoMoveIntoConstructor = + RootMathCommand.prototype.htmlTemplate = '&0'; + createBlocks () { + super.createBlocks.call(this); this.ends[L].cursor = this.cursor; this.ends[L].write = function(cursor, ch) { @@ -406,10 +412,10 @@ var RootMathCommand = P(MathCommand, function(_, super_) { MathBlock.prototype.write.call(this, cursor, ch); }; }; - _.latex = function() { + latex () { return '$' + this.ends[L].latex() + '$'; }; -}); +}; var RootTextBlock = P(RootMathBlock, function(_, super_) { _.keystroke = function(key) { diff --git a/src/services/latex.js b/src/services/latex.js index 03cb47c40..d28b2a5f6 100644 --- a/src/services/latex.js +++ b/src/services/latex.js @@ -313,7 +313,7 @@ Controller.open(function(_, super_) { .skip(string('$').or(eof)) .map(function(block) { // HACK FIXME: this shouldn't have to have access to cursor - var rootMathCommand = RootMathCommand(cursor); + var rootMathCommand = new RootMathCommand(cursor); rootMathCommand.createBlocks(); var rootMathBlock = rootMathCommand.ends[L]; From e41a1a816495f134887908a3b70590563de88957 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 15:18:36 -0500 Subject: [PATCH 015/192] convert RootTextBlock to ES6 class --- src/commands/text.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/text.js b/src/commands/text.js index f5373d16f..974d0483f 100644 --- a/src/commands/text.js +++ b/src/commands/text.js @@ -417,12 +417,12 @@ class RootMathCommand extends MathCommand { }; }; -var RootTextBlock = P(RootMathBlock, function(_, super_) { - _.keystroke = function(key) { +class RootTextBlock extends RootMathBlock { + keystroke (key) { if (key === 'Spacebar' || key === 'Shift-Spacebar') return; - return super_.keystroke.apply(this, arguments); + return super.keystroke.apply(this, arguments); }; - _.write = function(cursor, ch) { + write (cursor, ch) { cursor.show().deleteSelection(); if (ch === '$') RootMathCommand(cursor).createLeftOf(cursor); @@ -433,7 +433,7 @@ var RootTextBlock = P(RootMathBlock, function(_, super_) { new VanillaSymbol(ch, html).createLeftOf(cursor); } }; -}); +}; API.TextField = function(APIClasses) { return P(APIClasses.EditableField, function(_, super_) { this.RootBlock = RootTextBlock; From a22f53774b2635c12be429a63292feed6395377e Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 15:26:13 -0500 Subject: [PATCH 016/192] convert DigitGroupingChar to ES6 class --- src/commands/math/basicSymbols.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 9288e0d91..dff3ca7c5 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -1,15 +1,19 @@ /********************************* * Symbols for Basic Mathematics ********************************/ -var DigitGroupingChar = P(Symbol, function(_, super_) { - _.finalizeTree = _.siblingDeleted = _.siblingCreated = function(opts, dir) { +class DigitGroupingChar extends Symbol { + finalizeTree (opts, dir) { this.sharedSiblingMethod(opts, dir) }; + siblingDeleted (opts, dir) { this.sharedSiblingMethod(opts, dir) }; + siblingCreated (opts, dir) { this.sharedSiblingMethod(opts, dir) }; + + sharedSiblingMethod (opts, dir) { // don't try to fix digit grouping if the sibling to my right changed (dir === R or // undefined) and it's now a DigitGroupingChar, it will try to fix grouping if (dir !== L && this[R] instanceof DigitGroupingChar) return; this.fixDigitGrouping(opts); }; - _.fixDigitGrouping = function (opts) { + fixDigitGrouping (opts) { if (!opts.enableDigitGrouping) return; var left = this; @@ -83,7 +87,7 @@ var DigitGroupingChar = P(Symbol, function(_, super_) { } }; - _.removeGroupingBetween = function (left, right) { + removeGroupingBetween (left, right) { var node = left; do { node.setGroupingClass(undefined); @@ -91,7 +95,7 @@ var DigitGroupingChar = P(Symbol, function(_, super_) { } while (node = node[R]); }; - _.addGroupingBetween = function (start, end) { + addGroupingBetween (start, end) { var node = start; var count = 0; @@ -135,7 +139,7 @@ var DigitGroupingChar = P(Symbol, function(_, super_) { } }; - _.setGroupingClass = function (cls) { + setGroupingClass (cls) { // nothing changed (either class is the same or it's still undefined) if (this._groupingClass === cls) return; @@ -148,7 +152,7 @@ var DigitGroupingChar = P(Symbol, function(_, super_) { // cache the groupingClass this._groupingClass = cls; } -}); +}; var Digit = P(DigitGroupingChar, function(_, super_) { _.init = function(ch, html, mathspeak) { From 089b5a7db8ca9b58c8566331118ffb5468d01240 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 15:30:16 -0500 Subject: [PATCH 017/192] convert Digit to ES6 class --- src/commands/math.js | 2 +- src/commands/math/basicSymbols.js | 24 ++++++++++++++---------- src/commands/math/commands.js | 2 +- src/services/latex.js | 4 ++-- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/commands/math.js b/src/commands/math.js index f0484b158..9bd4e247f 100644 --- a/src/commands/math.js +++ b/src/commands/math.js @@ -524,7 +524,7 @@ class MathBlock extends MathElement { if (ch.match(/^[a-eg-zA-Z]$/)) return Letter(ch); else if (/^\d$/.test(ch)) - return Digit(ch); + return new Digit(ch); else if (options && options.typingSlashWritesDivisionSymbol && ch === '/') return LatexCmds['÷'](ch); else if (options && options.typingAsteriskWritesTimesSymbol && ch === '*') diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index dff3ca7c5..857414f3a 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -154,12 +154,16 @@ class DigitGroupingChar extends Symbol { } }; -var Digit = P(DigitGroupingChar, function(_, super_) { - _.init = function(ch, html, mathspeak) { - super_.init.call(this, ch, ''+(html || ch)+'', undefined, mathspeak); +class Digit extends DigitGroupingChar { + constructor (ch, html, mathspeak) { + super(); + this.init(ch, html, mathspeak); + } + init (ch, html, mathspeak) { + super.init.call(this, ch, ''+(html || ch)+'', undefined, mathspeak); }; - _.createLeftOf = function(cursor) { + createLeftOf (cursor) { if (cursor.options.autoSubscriptNumerals && cursor.parent !== cursor.parent.parent.sub && ((cursor[L] instanceof Variable && cursor[L].isItalic !== false) @@ -167,12 +171,12 @@ var Digit = P(DigitGroupingChar, function(_, super_) { && cursor[L][L] instanceof Variable && cursor[L][L].isItalic !== false))) { LatexCmds._().createLeftOf(cursor); - super_.createLeftOf.call(this, cursor); + super.createLeftOf.call(this, cursor); cursor.insRightOf(cursor.parent.parent); } - else super_.createLeftOf.call(this, cursor); + else super.createLeftOf.call(this, cursor); }; - _.mathspeak = function(opts) { + mathspeak (opts) { if (opts && opts.createdLeftOf) { var cursor = opts.createdLeftOf; if (cursor.options.autoSubscriptNumerals @@ -181,12 +185,12 @@ var Digit = P(DigitGroupingChar, function(_, super_) { || (cursor[L] instanceof SupSub && cursor[L][L] instanceof Variable && cursor[L][L].isItalic !== false))) { - return 'Subscript ' + super_.mathspeak.call(this) + ' Baseline'; + return 'Subscript ' + super.mathspeak.call(this) + ' Baseline'; } } - return super_.mathspeak.apply(this, arguments); + return super.mathspeak.apply(this, arguments); }; -}); +} var Variable = P(Symbol, function(_, super_) { _.init = function(ch, html) { diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 849dc311a..30b8d7215 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -791,7 +791,7 @@ var CubeRoot = LatexCmds.cbrt = P(NthRoot, function(_, super_) { _.createLeftOf = function(cursor) { super_.createLeftOf.apply(this, arguments); - Digit('3').createLeftOf(cursor); + new Digit('3').createLeftOf(cursor); cursor.controller.moveRight(); }; }); diff --git a/src/services/latex.js b/src/services/latex.js index d28b2a5f6..2e6d4ca27 100644 --- a/src/services/latex.js +++ b/src/services/latex.js @@ -27,7 +27,7 @@ var latexMathParser = (function() { // Parsers yielding either MathCommands, or Fragments of MathCommands // (either way, something that can be adopted by a MathBlock) var variable = letter.map(function(c) { return Letter(c); }); - var number = digit.map(function (c) { return Digit(c); }); + var number = digit.map(function (c) { return new Digit(c); }); var symbol = regex(/^[^${}\\_^]/).map(function(c) { return new VanillaSymbol(c); }); var controlSequence = @@ -229,7 +229,7 @@ Controller.open(function(_, super_) { span.className = "mq-digit"; span.textContent = newDigits[i]; - var newNode = Digit(newDigits[i]); + var newNode = new Digit(newDigits[i]); newNode.parent = root; newNode.jQ = $(span); frag.appendChild(span); From 4d4a29b41703da6214f42ab941df9455ba544ed9 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 16:18:04 -0500 Subject: [PATCH 018/192] pass bundle through typescript with es5 target --- Makefile | 6 +++--- script/tsc-emit-only | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100755 script/tsc-emit-only diff --git a/Makefile b/Makefile index 46f811553..4ad1ebd57 100644 --- a/Makefile +++ b/Makefile @@ -116,7 +116,7 @@ clean: $(PJS_SRC): $(NODE_MODULES_INSTALLED) $(BUILD_JS): $(INTRO) $(SOURCES_FULL) $(OUTRO) $(BUILD_DIR_EXISTS) - cat $^ | ./script/escape-non-ascii > $@ + cat $^ | ./script/escape-non-ascii | ./script/tsc-emit-only > $@ perl -pi -e s/mq-/$(MQ_CLASS_PREFIX)mq-/g $@ perl -pi -e s/{VERSION}/v$(VERSION)/ $@ @@ -124,7 +124,7 @@ $(UGLY_JS): $(BUILD_JS) $(NODE_MODULES_INSTALLED) $(UGLIFY) $(UGLIFY_OPTS) < $< > $@ $(BASIC_JS): $(INTRO) $(SOURCES_BASIC) $(OUTRO) $(BUILD_DIR_EXISTS) - cat $^ | ./script/escape-non-ascii > $@ + cat $^ | ./script/escape-non-ascii | ./script/tsc-emit-only > $@ perl -pi -e s/mq-/$(MQ_CLASS_PREFIX)mq-/g $@ perl -pi -e s/{VERSION}/v$(VERSION)/ $@ @@ -166,5 +166,5 @@ test: dev $(BUILD_TEST) $(BASIC_JS) $(BASIC_CSS) @echo "** now open test/{unit,visual}.html in your browser to run the {unit,visual} tests. **" $(BUILD_TEST): $(INTRO) $(SOURCES_FULL) $(UNIT_TESTS) $(OUTRO) $(BUILD_DIR_EXISTS) - cat $^ > $@ + cat $^ | ./script/tsc-emit-only > $@ perl -pi -e s/{VERSION}/v$(VERSION)/ $@ diff --git a/script/tsc-emit-only b/script/tsc-emit-only new file mode 100755 index 000000000..527ec982d --- /dev/null +++ b/script/tsc-emit-only @@ -0,0 +1,27 @@ +#!/usr/bin/env node + +var ts = require('typescript'); + +function compileTypescript (tsSource) { + compilerOptions = { + target: 'es5' + }; + + var jsSource = ts.transpileModule(tsSource, { + compilerOptions: compilerOptions + }).outputText; + + return jsSource; +} + +let contents = ''; + +process.stdin.setEncoding('utf8'); +process.stdin.on('data', function(data) { + contents += data; +}); +process.stdin.on('end', function () { + var ts = compileTypescript(contents); + console.log(ts); +}) +process.stdin.resume(); From 4215e40b6a17953e86dcc2c05c942078de156025 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 16:37:28 -0500 Subject: [PATCH 019/192] convert Variable to ES6 class --- src/commands/math/basicSymbols.js | 45 ++++++++++++++++++------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 857414f3a..ae1c15838 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -192,11 +192,16 @@ class Digit extends DigitGroupingChar { }; } -var Variable = P(Symbol, function(_, super_) { - _.init = function(ch, html) { - super_.init.call(this, ch, ''+(html || ch)+''); +class Variable extends Symbol { + constructor (ch, html) { + super(); + this.init(ch, html); + } + + init (ch, html) { + super.init.call(this, ch, ''+(html || ch)+''); }; - _.text = function() { + text () { var text = this.ctrlSeq; if (this.isPartOfOperator) { if (text[0] == '\\') { @@ -216,14 +221,14 @@ var Variable = P(Symbol, function(_, super_) { } return text; }; - _.mathspeak = function() { + mathspeak () { var text = this.ctrlSeq; if ( this.isPartOfOperator || text.length > 1 || (this.parent && this.parent.parent && this.parent.parent.isTextBlock()) ) { - return super_.mathspeak.call(this); + return super.mathspeak.call(this); } else { // Apple voices in VoiceOver (such as Alex, Bruce, and Victoria) do // some strange pronunciation given certain expressions, @@ -233,7 +238,11 @@ var Variable = P(Symbol, function(_, super_) { return '"'+text+'"'; } }; -}); +}; +function bindVariable (ch, html) { + return () => new Variable(ch, html); +} + Options.p.autoCommands = { _maxLength: 0 }; optionProcessors.autoCommands = function(cmds) { @@ -640,50 +649,50 @@ LatexCmds.omega = P(Variable, function(_, super_) { //why can't anybody FUCKING agree on these LatexCmds.phi = //W3C or Unicode? - bind(Variable,'\\phi ','ϕ', 'phi'); + bindVariable('\\phi ','ϕ', 'phi'); LatexCmds.phiv = //Elsevier and 9573-13 LatexCmds.varphi = //AMS and LaTeX - bind(Variable,'\\varphi ','φ', 'phi'); + bindVariable('\\varphi ','φ', 'phi'); LatexCmds.epsilon = //W3C or Unicode? - bind(Variable,'\\epsilon ','ϵ', 'epsilon'); + bindVariable('\\epsilon ','ϵ', 'epsilon'); LatexCmds.epsiv = //Elsevier and 9573-13 LatexCmds.varepsilon = //AMS and LaTeX - bind(Variable,'\\varepsilon ','ε', 'epsilon'); + bindVariable('\\varepsilon ','ε', 'epsilon'); LatexCmds.piv = //W3C/Unicode and Elsevier and 9573-13 LatexCmds.varpi = //AMS and LaTeX - bind(Variable,'\\varpi ','ϖ', 'piv'); + bindVariable('\\varpi ','ϖ', 'piv'); LatexCmds.sigmaf = //W3C/Unicode LatexCmds.sigmav = //Elsevier LatexCmds.varsigma = //LaTeX - bind(Variable,'\\varsigma ','ς', 'sigma'); + bindVariable('\\varsigma ','ς', 'sigma'); LatexCmds.thetav = //Elsevier and 9573-13 LatexCmds.vartheta = //AMS and LaTeX LatexCmds.thetasym = //W3C/Unicode - bind(Variable,'\\vartheta ','ϑ', 'theta'); + bindVariable('\\vartheta ','ϑ', 'theta'); LatexCmds.upsilon = //AMS and LaTeX and W3C/Unicode LatexCmds.upsi = //Elsevier and 9573-13 - bind(Variable,'\\upsilon ','υ', 'upsilon'); + bindVariable('\\upsilon ','υ', 'upsilon'); //these aren't even mentioned in the HTML character entity references LatexCmds.gammad = //Elsevier LatexCmds.Gammad = //9573-13 -- WTF, right? I dunno if this was a typo in the reference (see above) LatexCmds.digamma = //LaTeX - bind(Variable,'\\digamma ','ϝ', 'gamma'); + bindVariable('\\digamma ','ϝ', 'gamma'); LatexCmds.kappav = //Elsevier LatexCmds.varkappa = //AMS and LaTeX - bind(Variable,'\\varkappa ','ϰ', 'kappa'); + bindVariable('\\varkappa ','ϰ', 'kappa'); LatexCmds.rhov = //Elsevier and 9573-13 LatexCmds.varrho = //AMS and LaTeX - bind(Variable,'\\varrho ','ϱ', 'rho'); + bindVariable('\\varrho ','ϱ', 'rho'); //Greek constants, look best in non-italicized Times New Roman LatexCmds.pi = LatexCmds['π'] = bind(NonSymbolaSymbol,'\\pi ','π', 'pi'); From 2a3bb7fc8f27e0d3c4a0e10acd04523586820166 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 16:44:13 -0500 Subject: [PATCH 020/192] convert Letter to ES6 class --- src/commands/math.js | 2 +- src/commands/math/basicSymbols.js | 41 ++++++++++++++++++++----------- src/commands/math/commands.js | 2 +- src/services/latex.js | 2 +- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/commands/math.js b/src/commands/math.js index 9bd4e247f..13e47dc8d 100644 --- a/src/commands/math.js +++ b/src/commands/math.js @@ -522,7 +522,7 @@ class MathBlock extends MathElement { var cons; // exclude f because it gets a dedicated command with more spacing if (ch.match(/^[a-eg-zA-Z]$/)) - return Letter(ch); + return new Letter(ch); else if (/^\d$/.test(ch)) return new Digit(ch); else if (options && options.typingSlashWritesDivisionSymbol && ch === '/') diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index ae1c15838..a2db7d08c 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -283,9 +283,15 @@ optionProcessors.autoParenthesizedFunctions = function (cmds) { return dict; } -var Letter = P(Variable, function(_, super_) { - _.init = function(ch) { return super_.init.call(this, this.letter = ch); }; - _.checkAutoCmds = function (cursor) { +class Letter extends Variable { + constructor (ch) { + super(); + this.init(ch); + } + init (ch) { + return super.init.call(this, this.letter = ch); + }; + checkAutoCmds (cursor) { //handle autoCommands var autoCmds = cursor.options.autoCommands, maxLength = autoCmds._maxLength; if (maxLength > 0) { @@ -309,7 +315,7 @@ var Letter = P(Variable, function(_, super_) { } } - _.autoParenthesize = function (cursor) { + autoParenthesize (cursor) { //exit early if already parenthesized var right = cursor.parent.ends[R] if (right && right instanceof Bracket && right.ctrlSeq === '\\left(') { @@ -339,25 +345,30 @@ var Letter = P(Variable, function(_, super_) { } } - _.createLeftOf = function(cursor) { - super_.createLeftOf.apply(this, arguments); + createLeftOf (cursor) { + super.createLeftOf.apply(this, arguments); this.checkAutoCmds(cursor); this.autoParenthesize(cursor); }; - _.italicize = function(bool) { + italicize (bool) { this.isItalic = bool; this.isPartOfOperator = !bool; this.jQ.toggleClass('mq-operator-name', !bool); return this; }; - _.finalizeTree = _.siblingDeleted = _.siblingCreated = function(opts, dir) { + finalizeTree (opts, dir) {this.sharedSiblingMethod(opts, dir)}; + siblingDeleted (opts, dir) {this.sharedSiblingMethod(opts, dir)}; + siblingCreated (opts, dir) {this.sharedSiblingMethod(opts, dir)}; + + sharedSiblingMethod (opts, dir) { // don't auto-un-italicize if the sibling to my right changed (dir === R or // undefined) and it's now a Letter, it will un-italicize everyone if (dir !== L && this[R] instanceof Letter) return; this.autoUnItalicize(opts); }; - _.autoUnItalicize = function(opts) { + + autoUnItalicize (opts) { var autoOps = opts.autoOperatorNames; if (autoOps._maxLength === 0) return; @@ -394,8 +405,8 @@ var Letter = P(Variable, function(_, super_) { first.ctrlSeq = (isBuiltIn ? '\\' : '\\operatorname{') + first.ctrlSeq; last.ctrlSeq += (isBuiltIn ? ' ' : '}'); if (TwoWordOpNames.hasOwnProperty(word)) last[L][L][L].jQ.addClass('mq-last'); - if (!shouldOmitPadding(first[L])) first.jQ.addClass('mq-first'); - if (!shouldOmitPadding(last[R])) { + if (!this.shouldOmitPadding(first[L])) first.jQ.addClass('mq-first'); + if (!this.shouldOmitPadding(last[R])) { if (last[R] instanceof SupSub) { var supsub = last[R]; // XXX monkey-patching, but what's the right thing here? // Have operatorname-specific code in SupSub? A CSS-like language to style the @@ -417,7 +428,7 @@ var Letter = P(Variable, function(_, super_) { } } }; - function shouldOmitPadding(node) { + shouldOmitPadding(node) { // omit padding if no node if (!node) return true; @@ -432,7 +443,7 @@ var Letter = P(Variable, function(_, super_) { return false; } -}); +}; var BuiltInOpNames = {}; // the set of operator names like \sin, \cos, etc that // are built-into LaTeX, see Section 3.17 of the Short Math Guide: http://tinyurl.com/jm9okjc // MathQuill auto-unitalicizes some operator names not in that set, like 'hcf' @@ -509,14 +520,14 @@ var OperatorName = P(Symbol, function(_, super_) { _.createLeftOf = function(cursor) { var fn = this.ctrlSeq; for (var i = 0; i < fn.length; i += 1) { - Letter(fn.charAt(i)).createLeftOf(cursor); + new Letter(fn.charAt(i)).createLeftOf(cursor); } }; _.parser = function() { var fn = this.ctrlSeq; var block = new MathBlock(); for (var i = 0; i < fn.length; i += 1) { - Letter(fn.charAt(i)).adopt(block, block.ends[R], 0); + new Letter(fn.charAt(i)).adopt(block, block.ends[R], 0); } return Parser.succeed(block.children()); }; diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 30b8d7215..9237e58c7 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -474,7 +474,7 @@ var SummationNotation = P(MathCommand, function(_, super_) { _.createLeftOf = function(cursor) { super_.createLeftOf.apply(this, arguments); if (cursor.options.sumStartsWithNEquals) { - Letter('n').createLeftOf(cursor); + new Letter('n').createLeftOf(cursor); Equality().createLeftOf(cursor); } }; diff --git a/src/services/latex.js b/src/services/latex.js index 2e6d4ca27..58c0e8ede 100644 --- a/src/services/latex.js +++ b/src/services/latex.js @@ -26,7 +26,7 @@ var latexMathParser = (function() { // Parsers yielding either MathCommands, or Fragments of MathCommands // (either way, something that can be adopted by a MathBlock) - var variable = letter.map(function(c) { return Letter(c); }); + var variable = letter.map(function(c) { return new Letter(c); }); var number = digit.map(function (c) { return new Digit(c); }); var symbol = regex(/^[^${}\\_^]/).map(function(c) { return new VanillaSymbol(c); }); From de283194475980111c2227cfb018e30f62b8f464 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 19:49:25 -0500 Subject: [PATCH 021/192] convert OperatorName to ES6 class --- src/commands/math/basicSymbols.js | 24 +++++++++++++++++------- test/unit/typing.test.js | 2 +- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index a2db7d08c..2aa08d752 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -255,7 +255,7 @@ optionProcessors.autoCommands = function(cmds) { if (cmd.length < 2) { throw 'autocommand "'+cmd+'" not minimum length of 2'; } - if (LatexCmds[cmd] === OperatorName) { + if (LatexCmds[cmd] === OperatorName || LatexCmds[cmd] === makeOperatorName) { throw '"' + cmd + '" is a built-in operator name'; } dict[cmd] = 1; @@ -515,15 +515,22 @@ optionProcessors.autoOperatorNames = function(cmds) { dict._maxLength = maxLength; return dict; }; -var OperatorName = P(Symbol, function(_, super_) { - _.init = function(fn) { this.ctrlSeq = fn; }; - _.createLeftOf = function(cursor) { +class OperatorName extends Symbol { + constructor (fn) { + // super(); -- did not have super() originally + this.init(fn); + } + init (fn) { + // did not call super.init() originally + this.ctrlSeq = fn; + }; + createLeftOf (cursor) { var fn = this.ctrlSeq; for (var i = 0; i < fn.length; i += 1) { new Letter(fn.charAt(i)).createLeftOf(cursor); } }; - _.parser = function() { + parser () { var fn = this.ctrlSeq; var block = new MathBlock(); for (var i = 0; i < fn.length; i += 1) { @@ -531,9 +538,12 @@ var OperatorName = P(Symbol, function(_, super_) { } return Parser.succeed(block.children()); }; -}); +}; for (var fn in AutoOpNames) if (AutoOpNames.hasOwnProperty(fn)) { - LatexCmds[fn] = OperatorName; + LatexCmds[fn] = makeOperatorName; +} +function makeOperatorName (fn) { + return new OperatorName(fn); } LatexCmds.operatorname = P(MathCommand, function(_) { _.createLeftOf = noop; diff --git a/test/unit/typing.test.js b/test/unit/typing.test.js index b5148128e..af71be70b 100644 --- a/test/unit/typing.test.js +++ b/test/unit/typing.test.js @@ -1239,7 +1239,7 @@ suite('typing with auto-replaces', function() { test('built-in operator names even after auto-operator names overridden', function() { MQ.config({ autoOperatorNames: 'sin inf arcosh cosh cos cosec csc' }); - // ^ happen to be the ones required by autoOperatorNames.test.js + // ^ happen to be the ones required by autoOperatorNames.test.js var cmds = 'Pr arg deg det exp gcd inf lg lim ln log max min sup'.split(' '); for (var i = 0; i < cmds.length; i += 1) { assert.throws(function() { MQ.config({ autoCommands: cmds[i] }) }, From dad0fd83cef6d079f329ba2b9c26ec95ee727435 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 23:23:32 -0500 Subject: [PATCH 022/192] convert LatexCcmds.operatorname to ES6 class --- src/commands/math/basicSymbols.js | 10 +++++----- src/services/latex.js | 6 +++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 2aa08d752..8b6705316 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -545,10 +545,10 @@ for (var fn in AutoOpNames) if (AutoOpNames.hasOwnProperty(fn)) { function makeOperatorName (fn) { return new OperatorName(fn); } -LatexCmds.operatorname = P(MathCommand, function(_) { - _.createLeftOf = noop; - _.numBlocks = function() { return 1; }; - _.parser = function() { +LatexCmds.operatorname = class extends MathCommand { + createLeftOf () {}; + numBlocks () { return 1; }; + parser () { return latexMathParser.block.map(function(b) { // Check for the special case of \operatorname{ans}, which has // a special html representation @@ -567,7 +567,7 @@ LatexCmds.operatorname = P(MathCommand, function(_) { return children; }); }; -}); +}; LatexCmds.f = P(Letter, function(_, super_) { _.init = function() { diff --git a/src/services/latex.js b/src/services/latex.js index 58c0e8ede..a02282cf4 100644 --- a/src/services/latex.js +++ b/src/services/latex.js @@ -40,7 +40,11 @@ var latexMathParser = (function() { var cmdKlass = LatexCmds[ctrlSeq]; if (cmdKlass) { - return cmdKlass(ctrlSeq).parser(); + if (cmdKlass.constructor) { + return new cmdKlass(ctrlSeq).parser(); + } else { + return cmdKlass(ctrlSeq).parser(); + } } else { return fail('unknown command: \\'+ctrlSeq); From 1d7d0360b9b6bb1040a3dbac501c1f2db75b379a Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 23:26:33 -0500 Subject: [PATCH 023/192] convert LatexCcmds.f to ES6 class --- src/commands/math.js | 6 +++++- src/commands/math/basicSymbols.js | 10 +++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/commands/math.js b/src/commands/math.js index 13e47dc8d..90d49a31b 100644 --- a/src/commands/math.js +++ b/src/commands/math.js @@ -532,7 +532,11 @@ class MathBlock extends MathElement { else if (options && options.typingPercentWritesPercentOf && ch === '%') return LatexCmds.percentof(ch); else if (cons = CharCmds[ch] || LatexCmds[ch]) { - return cons(ch); + if (cons.constructor) { + return new cons(ch); + } else { + return cons(ch); + } } else return new VanillaSymbol(ch); diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 8b6705316..713a426ef 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -569,15 +569,15 @@ LatexCmds.operatorname = class extends MathCommand { }; }; -LatexCmds.f = P(Letter, function(_, super_) { - _.init = function() { +LatexCmds.f = class extends Letter { + init () { Symbol.prototype.init.call(this, this.letter = 'f', 'f'); }; - _.italicize = function(bool) { + italicize (bool) { this.jQ.html('f').toggleClass('mq-f', bool); - return super_.italicize.apply(this, arguments); + return super.italicize.apply(this, arguments); }; -}); +}; // VanillaSymbol's LatexCmds[' '] = LatexCmds.space = P(DigitGroupingChar, function(_, super_) { From fcec2a0fa244c59ed1ccc5f669fb97f0a008c07d Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 23:29:14 -0500 Subject: [PATCH 024/192] convert LatexCmds space and period to ES6 class --- src/commands/math/basicSymbols.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 713a426ef..9772983fb 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -580,17 +580,17 @@ LatexCmds.f = class extends Letter { }; // VanillaSymbol's -LatexCmds[' '] = LatexCmds.space = P(DigitGroupingChar, function(_, super_) { - _.init = function () { - super_.init.call(this, '\\ ', ' ', ' '); +LatexCmds[' '] = LatexCmds.space = class extends DigitGroupingChar { + init () { + super.init.call(this, '\\ ', ' ', ' '); }; -}); +}; -LatexCmds['.'] = P(DigitGroupingChar, function(_, super_) { - _.init = function () { - super_.init.call(this, '.', '.', '.'); +LatexCmds['.'] = class extends DigitGroupingChar { + init () { + super.init.call(this, '.', '.', '.'); }; -}); +}; LatexCmds["'"] = LatexCmds.prime = bindVanillaSymbol("'", '′', 'prime'); LatexCmds['″'] = LatexCmds.dprime = bindVanillaSymbol('″', '″', 'double prime'); From b4ed1d178aa0c7babfeaabf0a7be9c8daebb9bed Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 23:39:35 -0500 Subject: [PATCH 025/192] convert NonSymbolaSymbol to ES6 class --- src/commands/math/basicSymbols.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 9772983fb..e9b252477 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -604,14 +604,19 @@ LatexCmds.square = bindVanillaSymbol('\\square ', '\u25A1', 'square'); LatexCmds.mid = bindVanillaSymbol('\\mid ', '\u2223', 'mid'); // does not use Symbola font -var NonSymbolaSymbol = P(Symbol, function(_, super_) { - _.init = function(ch, html) { - super_.init.call(this, ch, ''+(html || ch)+''); +class NonSymbolaSymbol extends Symbol { + constructor (ch, html) { + super(); + this.init(ch, html); + } + + init (ch, html) { + super.init.call(this, ch, ''+(html || ch)+''); }; -}); +}; LatexCmds['@'] = NonSymbolaSymbol; -LatexCmds['&'] = bind(NonSymbolaSymbol, '\\&', '&', 'and'); +LatexCmds['&'] = () => new NonSymbolaSymbol('\\&', '&', 'and'); LatexCmds['%'] = P(NonSymbolaSymbol, function(_, super_) { _.init = function () { super_.init.call(this, '\\%', '%', 'percent'); @@ -716,8 +721,8 @@ LatexCmds.varrho = //AMS and LaTeX bindVariable('\\varrho ','ϱ', 'rho'); //Greek constants, look best in non-italicized Times New Roman -LatexCmds.pi = LatexCmds['π'] = bind(NonSymbolaSymbol,'\\pi ','π', 'pi'); -LatexCmds.lambda = bind(NonSymbolaSymbol,'\\lambda ','λ', 'lambda'); +LatexCmds.pi = LatexCmds['π'] = () => new NonSymbolaSymbol('\\pi ','π', 'pi'); +LatexCmds.lambda = () => new NonSymbolaSymbol('\\lambda ','λ', 'lambda'); //uppercase greek letters From b6b122f08a4dc860a802b4e5592ef39e14cb6807 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 23:41:50 -0500 Subject: [PATCH 026/192] convert % to ES6 class --- src/commands/math/basicSymbols.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index e9b252477..fe5c7689f 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -617,11 +617,11 @@ class NonSymbolaSymbol extends Symbol { LatexCmds['@'] = NonSymbolaSymbol; LatexCmds['&'] = () => new NonSymbolaSymbol('\\&', '&', 'and'); -LatexCmds['%'] = P(NonSymbolaSymbol, function(_, super_) { - _.init = function () { - super_.init.call(this, '\\%', '%', 'percent'); +LatexCmds['%'] = class extends NonSymbolaSymbol { + init () { + super.init.call(this, '\\%', '%', 'percent'); }; - _.parser = function () { + parser () { var optWhitespace = Parser.optWhitespace; var string = Parser.string; @@ -633,10 +633,10 @@ LatexCmds['%'] = P(NonSymbolaSymbol, function(_, super_) { .map(function () { return LatexCmds.percentof(); }) - ).or(super_.parser.call(this)) + ).or(super.parser.call(this)) ; } -}); +}; LatexCmds['∥'] = LatexCmds.parallel = bindVanillaSymbol('\\parallel ', '∥', 'parallel'); From 5187aec772a4c9c88d4f94a6e1aaf0fe43737733 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 23:53:38 -0500 Subject: [PATCH 027/192] convert greek letters to ES6 class --- src/commands/math/basicSymbols.js | 22 +++++++++++----------- src/publicapi.js | 6 +++++- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index fe5c7689f..c3ddcf291 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -308,7 +308,15 @@ class Letter extends Variable { for (var i = 1, l = this; i < str.length; i += 1, l = l[L]); new Fragment(l, this).remove(); cursor[L] = l[L]; - return LatexCmds[str](str).createLeftOf(cursor); + + var cmd = LatexCmds[str]; + if (cmd.constructor) { + cmd = new cmd(str); + } else { + cmd = cmd(str); + } + + return cmd.createLeftOf(cursor); } str = str.slice(1); } @@ -667,11 +675,7 @@ LatexCmds.sigma = LatexCmds.tau = LatexCmds.chi = LatexCmds.psi = -LatexCmds.omega = P(Variable, function(_, super_) { - _.init = function(latex) { - super_.init.call(this,'\\'+latex+' ','&'+latex+';'); - }; -}); +LatexCmds.omega = (latex) => new Variable('\\'+latex+' ','&'+latex+';'); //why can't anybody FUCKING agree on these LatexCmds.phi = //W3C or Unicode? @@ -743,11 +747,7 @@ LatexCmds.Sigma = LatexCmds.Phi = LatexCmds.Psi = LatexCmds.Omega = -LatexCmds.forall = P(VanillaSymbol, function(_, super_) { - _.init = function(latex) { - super_.init.call(this,'\\'+latex+' ','&'+latex+';'); - }; -}); +LatexCmds.forall = (latex) => new VanillaSymbol('\\'+latex+' ','&'+latex+';') // symbols that aren't a single MathCommand, but are instead a whole // Fragment. Creates the Fragment from a LaTeX string diff --git a/src/publicapi.js b/src/publicapi.js index 9d5336b11..3253b2c5b 100644 --- a/src/publicapi.js +++ b/src/publicapi.js @@ -180,7 +180,11 @@ function getInterface(v) { cmd = cmd.slice(1); var klass = LatexCmds[cmd]; if (klass) { - cmd = klass(cmd); + if (klass.constructor) { + cmd = new klass(cmd); + } else { + cmd = klass(cmd); + } if (cursor.selection) cmd.replaces(cursor.replaceSelection()); cmd.createLeftOf(cursor.show()); } From 739c72c2f464025ba5c5e6983720e7b28b93354a Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Tue, 30 Nov 2021 23:58:22 -0500 Subject: [PATCH 028/192] convert LatexFragment to ES6 class --- src/commands/math/basicSymbols.js | 44 ++++++++++++++++--------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index c3ddcf291..8657f936d 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -751,9 +751,11 @@ LatexCmds.forall = (latex) => new VanillaSymbol('\\'+latex+' ','&'+latex+';') // symbols that aren't a single MathCommand, but are instead a whole // Fragment. Creates the Fragment from a LaTeX string -var LatexFragment = P(MathCommand, function(_) { - _.init = function(latex) { this.latex = latex; }; - _.createLeftOf = function(cursor) { +class LatexFragment extends MathCommand { + init (latex) { + this.latex = latex; + } + createLeftOf (cursor) { var block = latexMathParser.parse(this.latex); block.children().adopt(cursor.parent, cursor[L], cursor[R]); cursor[L] = block.ends[R]; @@ -763,12 +765,12 @@ var LatexFragment = P(MathCommand, function(_) { if (block.ends[L][L].siblingCreated) block.ends[L][L].siblingCreated(cursor.options, R); cursor.parent.bubble(function (node) { node.reflow(); }); }; - _.mathspeak = function() { return latexMathParser.parse(this.latex).mathspeak(); }; - _.parser = function() { + mathspeak () { return latexMathParser.parse(this.latex).mathspeak(); }; + parser () { var frag = latexMathParser.parse(this.latex).children(); return Parser.succeed(frag); }; -}); +}; // for what seems to me like [stupid reasons][1], Unicode provides // subscripted and superscripted versions of all ten Arabic numerals, @@ -794,20 +796,20 @@ var LatexFragment = P(MathCommand, function(_) { // [2]: http://en.wikipedia.org/wiki/Number_Forms // [3]: http://en.wikipedia.org/wiki/ISO/IEC_8859-1 // [4]: http://en.wikipedia.org/wiki/Windows-1252 -LatexCmds['⁰'] = bind(LatexFragment, '^0'); -LatexCmds['¹'] = bind(LatexFragment, '^1'); -LatexCmds['²'] = bind(LatexFragment, '^2'); -LatexCmds['³'] = bind(LatexFragment, '^3'); -LatexCmds['⁴'] = bind(LatexFragment, '^4'); -LatexCmds['⁵'] = bind(LatexFragment, '^5'); -LatexCmds['⁶'] = bind(LatexFragment, '^6'); -LatexCmds['⁷'] = bind(LatexFragment, '^7'); -LatexCmds['⁸'] = bind(LatexFragment, '^8'); -LatexCmds['⁹'] = bind(LatexFragment, '^9'); - -LatexCmds['¼'] = bind(LatexFragment, '\\frac14'); -LatexCmds['½'] = bind(LatexFragment, '\\frac12'); -LatexCmds['¾'] = bind(LatexFragment, '\\frac34'); +LatexCmds['⁰'] = () => new LatexFragment('^0'); +LatexCmds['¹'] = () => new LatexFragment('^1'); +LatexCmds['²'] = () => new LatexFragment('^2'); +LatexCmds['³'] = () => new LatexFragment('^3'); +LatexCmds['⁴'] = () => new LatexFragment('^4'); +LatexCmds['⁵'] = () => new LatexFragment('^5'); +LatexCmds['⁶'] = () => new LatexFragment('^6'); +LatexCmds['⁷'] = () => new LatexFragment('^7'); +LatexCmds['⁸'] = () => new LatexFragment('^8'); +LatexCmds['⁹'] = () => new LatexFragment('^9'); + +LatexCmds['¼'] = () => new LatexFragment('\\frac14'); +LatexCmds['½'] = () => new LatexFragment('\\frac12'); +LatexCmds['¾'] = () => new LatexFragment('\\frac34'); // this is a hack to make pasting the √ symbol // actually insert a sqrt command. This isn't ideal, @@ -831,7 +833,7 @@ LatexCmds['¾'] = bind(LatexFragment, '\\frac34'); // act more like simply typing the characters out. I'd be scared to try // to make that change because I'm fairly confident I'd break something // around handling valid latex as latex rather than treating it as keystrokes. -LatexCmds['√'] = bind(LatexFragment, '\\sqrt{}'); +LatexCmds['√'] = () => new LatexFragment('\\sqrt{}'); // Binary operator determination is used in several contexts for PlusMinus nodes and their descendants. // For instance, we set the item's class name based on this factor, and also assign different mathspeak values (plus vs positive, negative vs minus). From 88cb05bb60a240ef293c00f06386f6e833249012 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 08:12:38 -0500 Subject: [PATCH 029/192] convert makeTextBlock to ES6 class --- src/commands/math/LatexCommandInput.js | 6 +++++- src/commands/text.js | 17 ++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/commands/math/LatexCommandInput.js b/src/commands/math/LatexCommandInput.js index 6faa9bd62..6d527d7d7 100644 --- a/src/commands/math/LatexCommandInput.js +++ b/src/commands/math/LatexCommandInput.js @@ -85,7 +85,11 @@ CharCmds['\\'] = P(MathCommand, function(_, super_) { if (!latex) latex = ' '; var cmd = LatexCmds[latex]; if (cmd) { - cmd = cmd(latex); + if (cmd.constructor) { + cmd = new cmd(latex); + } else { + cmd = cmd(latex); + } if (this._replacedFragment) cmd.replaces(this._replacedFragment); cmd.createLeftOf(cursor); } diff --git a/src/commands/text.js b/src/commands/text.js index 974d0483f..ed578ce28 100644 --- a/src/commands/text.js +++ b/src/commands/text.js @@ -352,15 +352,18 @@ LatexCmds.textup = LatexCmds.textmd = P(TextBlock, {}); function makeTextBlock(latex, ariaLabel, tagName, attrs) { - return P(TextBlock, { - ctrlSeq: latex, - ariaLabel: ariaLabel, - mathspeakTemplate: ['Start'+ariaLabel, 'End'+ariaLabel], - html: function() { + var klass = class extends TextBlock { + html () { var cmdId = 'mathquill-command-id=' + this.id; return '<'+tagName+' '+attrs+' '+cmdId+'>'+this.textContents()+''; - } - }); + } + }; + + klass.prototype.ctrlSeq = latex; + klass.prototype.ariaLabel = ariaLabel; + klass.prototype.mathspeakTemplate = ['Start'+ariaLabel, 'End'+ariaLabel]; + + return klass; } LatexCmds.em = LatexCmds.italic = LatexCmds.italics = From 828dd2691d4239cc5490f5d555c23e4688deb71a Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 08:20:53 -0500 Subject: [PATCH 030/192] remove TextBlock extension and makOperatorName --- src/commands/math/basicSymbols.js | 7 ++----- src/commands/text.js | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 8657f936d..a30a4beab 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -255,7 +255,7 @@ optionProcessors.autoCommands = function(cmds) { if (cmd.length < 2) { throw 'autocommand "'+cmd+'" not minimum length of 2'; } - if (LatexCmds[cmd] === OperatorName || LatexCmds[cmd] === makeOperatorName) { + if (LatexCmds[cmd] === OperatorName) { throw '"' + cmd + '" is a built-in operator name'; } dict[cmd] = 1; @@ -548,10 +548,7 @@ class OperatorName extends Symbol { }; }; for (var fn in AutoOpNames) if (AutoOpNames.hasOwnProperty(fn)) { - LatexCmds[fn] = makeOperatorName; -} -function makeOperatorName (fn) { - return new OperatorName(fn); + LatexCmds[fn] = OperatorName; } LatexCmds.operatorname = class extends MathCommand { createLeftOf () {}; diff --git a/src/commands/text.js b/src/commands/text.js index ed578ce28..39cba9383 100644 --- a/src/commands/text.js +++ b/src/commands/text.js @@ -349,7 +349,7 @@ LatexCmds.text = LatexCmds.textnormal = LatexCmds.textrm = LatexCmds.textup = -LatexCmds.textmd = P(TextBlock, {}); +LatexCmds.textmd = TextBlock; function makeTextBlock(latex, ariaLabel, tagName, attrs) { var klass = class extends TextBlock { From cc59cc72597aa45ef2dd04d8e12063c453ef2695 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 08:28:13 -0500 Subject: [PATCH 031/192] convert LatexCmds.notin to ES6 class --- src/commands/math/advancedSymbols.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/commands/math/advancedSymbols.js b/src/commands/math/advancedSymbols.js index 7b66f2d7c..6b9fb0b90 100644 --- a/src/commands/math/advancedSymbols.js +++ b/src/commands/math/advancedSymbols.js @@ -6,11 +6,7 @@ LatexCmds.notin = LatexCmds.cong = LatexCmds.equiv = LatexCmds.oplus = -LatexCmds.otimes = P(BinaryOperator, function(_, super_) { - _.init = function(latex) { - super_.init.call(this, '\\'+latex+' ', '&'+latex+';'); - }; -}); +LatexCmds.otimes = (latex) => new BinaryOperator('\\'+latex+' ', '&'+latex+';'); LatexCmds['∗'] = LatexCmds.ast = LatexCmds.star = LatexCmds.loast = LatexCmds.lowast = bindBinaryOperator('\\ast ','∗', 'low asterisk'); From 002c58ebf3e26701ba594a402e70317e08e13d5e Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 08:32:51 -0500 Subject: [PATCH 032/192] convert LatexCmds.mathbb to ES6 class --- src/commands/math/advancedSymbols.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/commands/math/advancedSymbols.js b/src/commands/math/advancedSymbols.js index 6b9fb0b90..6ff913817 100644 --- a/src/commands/math/advancedSymbols.js +++ b/src/commands/math/advancedSymbols.js @@ -64,10 +64,10 @@ LatexCmds.notsupersete = LatexCmds.notsuperseteq = bindBinaryOperator('\\not\\supseteq ','⊉', 'not superset or equal to'); //the canonical sets of numbers -LatexCmds.mathbb = P(MathCommand, function(_) { - _.createLeftOf = noop; - _.numBlocks = function() { return 1; }; - _.parser = function() { +LatexCmds.mathbb = class extends MathCommand { + createLeftOf () {}; + numBlocks () { return 1; }; + parser () { var string = Parser.string; var regex = Parser.regex; var optWhitespace = Parser.optWhitespace; @@ -78,10 +78,15 @@ LatexCmds.mathbb = P(MathCommand, function(_) { .skip(string('}')) .map(function(c) { // instantiate the class for the matching char - return LatexCmds[c](); - }); + var cmd = LatexCmds[c]; + if (cmd.constructor) { + return new cmd(); + } else { + return cmd(); + } + }); }; -}); +}; LatexCmds.N = LatexCmds.naturals = LatexCmds.Naturals = bindVanillaSymbol('\\mathbb{N}','ℕ', 'naturals'); From 1428586e2892a0cbfeda82c07a6d73fd52f89832 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 08:37:41 -0500 Subject: [PATCH 033/192] simplify space and . LatexCmds --- src/commands/math/basicSymbols.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index a30a4beab..60bdf7193 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -585,17 +585,9 @@ LatexCmds.f = class extends Letter { }; // VanillaSymbol's -LatexCmds[' '] = LatexCmds.space = class extends DigitGroupingChar { - init () { - super.init.call(this, '\\ ', ' ', ' '); - }; -}; +LatexCmds[' '] = LatexCmds.space = () => new DigitGroupingChar('\\ ', ' ', ' '); -LatexCmds['.'] = class extends DigitGroupingChar { - init () { - super.init.call(this, '.', '.', '.'); - }; -}; +LatexCmds['.'] = () => new DigitGroupingChar('.', '.', '.') LatexCmds["'"] = LatexCmds.prime = bindVanillaSymbol("'", '′', 'prime'); LatexCmds['″'] = LatexCmds.dprime = bindVanillaSymbol('″', '″', 'double prime'); From 62d9ff099a25ecc8f88edfd2f85c4939fab20027 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 08:55:34 -0500 Subject: [PATCH 034/192] convert PlusMinus to ES6 class --- src/commands/math/basicSymbols.js | 23 +++++++++++++++++------ src/services/latex.js | 2 +- test/unit/css.test.js | 1 - 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 60bdf7193..8a73a64e4 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -846,10 +846,21 @@ function isBinaryOperator(node) { return true; } -var PlusMinus = P(BinaryOperator, function(_) { +var PlusMinus = class extends BinaryOperator { + constructor (ch, html, mathspeak) { + super(); + this.init(ch, html, mathspeak); + } - _.init = VanillaSymbol.prototype.init; - _.contactWeld = _.siblingCreated = _.siblingDeleted = function(opts, dir) { + init (ch, html, mathspeak) { + Symbol.prototype.init.call(this, ch, ''+(html || ch)+'', undefined, mathspeak); + }; + + contactWeld (opts, dir) { this.sharedSiblingMethod(opts, dir)} + siblingCreated (opts, dir) { this.sharedSiblingMethod(opts, dir)} + siblingDeleted (opts, dir) { this.sharedSiblingMethod(opts, dir)} + + sharedSiblingMethod (opts, dir) { if (dir === R) return; // ignore if sibling only changed on the right this.jQ[0].className = isBinaryOperator(this) ? 'mq-binary-operator' @@ -857,7 +868,7 @@ var PlusMinus = P(BinaryOperator, function(_) { return this; }; -}); +}; LatexCmds['+'] = P(PlusMinus, function(_, super_) { _.init = function () { @@ -879,9 +890,9 @@ LatexCmds['−'] = LatexCmds['—'] = LatexCmds['–'] = LatexCmds['-'] = P(Plus }); LatexCmds['±'] = LatexCmds.pm = LatexCmds.plusmn = LatexCmds.plusminus = - bind(PlusMinus,'\\pm ','±', 'plus-or-minus'); + () => new PlusMinus('\\pm ','±', 'plus-or-minus'); LatexCmds.mp = LatexCmds.mnplus = LatexCmds.minusplus = - bind(PlusMinus,'\\mp ','∓', 'minus-or-plus'); + () => new PlusMinus('\\mp ','∓', 'minus-or-plus'); CharCmds['*'] = LatexCmds.sdot = LatexCmds.cdot = bindBinaryOperator('\\cdot ', '·', '*', 'times'); //semantically should be ⋅, but · looks better diff --git a/src/services/latex.js b/src/services/latex.js index a02282cf4..42f3fc24a 100644 --- a/src/services/latex.js +++ b/src/services/latex.js @@ -184,7 +184,7 @@ Controller.open(function(_, super_) { // add a minus sign if (!oldMinusSign && newMinusSign) { - var newMinusNode = PlusMinus('-'); + var newMinusNode = new PlusMinus('-'); var minusSpan = document.createElement('span'); minusSpan.textContent = '-'; newMinusNode.jQ = $(minusSpan); diff --git a/test/unit/css.test.js b/test/unit/css.test.js index 5cc6fb798..edc0d1b3c 100644 --- a/test/unit/css.test.js +++ b/test/unit/css.test.js @@ -48,7 +48,6 @@ suite('CSS', function() { mq.latex('(-1,-1-1)-1,(+1;+1+1)+1,(\\pm1,\\pm1\\pm1)\\pm1'); var spans = $(mq.el()).find('.mq-root-block').find('span'); assert.equal(spans.length, 35, 'PlusMinus expression parsed incorrectly'); - function isBinaryOperator(i) { return $(spans[i]).hasClass('mq-binary-operator'); } function assertBinaryOperator(i, s) { assert.ok(isBinaryOperator(i), '"' + s + '" should be binary'); } function assertUnaryOperator(i, s) { assert.ok(!isBinaryOperator(i), '"' + s + '" should be unary'); } From c9a651368c4c5199b893dbe46e6f1e7c6c2c62cd Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 09:00:35 -0500 Subject: [PATCH 035/192] convert + and - to ES6 class --- src/commands/math/basicSymbols.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 8a73a64e4..24b6cbdf7 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -870,24 +870,24 @@ var PlusMinus = class extends BinaryOperator { }; }; -LatexCmds['+'] = P(PlusMinus, function(_, super_) { - _.init = function () { - super_.init.call(this, '+', '+'); +LatexCmds['+'] = class extends PlusMinus { + init () { + super.init.call(this, '+', '+'); }; - _.mathspeak = function() { + mathspeak () { return isBinaryOperator(this) ? 'plus' : 'positive'; }; -}); +}; //yes, these are different dashes, en-dash, em-dash, unicode minus, actual dash -LatexCmds['−'] = LatexCmds['—'] = LatexCmds['–'] = LatexCmds['-'] = P(PlusMinus, function(_, super_) { - _.init = function () { - super_.init.call(this, '-', '−'); +LatexCmds['−'] = LatexCmds['—'] = LatexCmds['–'] = LatexCmds['-'] = class extends PlusMinus { + init () { + super.init.call(this, '-', '−'); }; - _.mathspeak = function() { + mathspeak () { return isBinaryOperator(this) ? 'minus' : 'negative'; }; -}); +}; LatexCmds['±'] = LatexCmds.pm = LatexCmds.plusmn = LatexCmds.plusminus = () => new PlusMinus('\\pm ','±', 'plus-or-minus'); @@ -906,7 +906,7 @@ var To = P(BinaryOperator, function(_, super_) { var l = cursor[L]; new Fragment(l, this).remove(); cursor[L] = l[L]; - LatexCmds['−']().createLeftOf(cursor); + new LatexCmds['−']().createLeftOf(cursor); cursor[L].bubble(function (node) { node.reflow(); }); return; } From e439dd43e18acb24373047dcb6f9a1a000137027 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 09:04:47 -0500 Subject: [PATCH 036/192] convert To to ES6 class --- src/commands/math/basicSymbols.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 24b6cbdf7..9646e1d0d 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -897,11 +897,11 @@ LatexCmds.mp = LatexCmds.mnplus = LatexCmds.minusplus = CharCmds['*'] = LatexCmds.sdot = LatexCmds.cdot = bindBinaryOperator('\\cdot ', '·', '*', 'times'); //semantically should be ⋅, but · looks better -var To = P(BinaryOperator, function(_, super_) { - _.init = function() { - super_.init.call(this, '\\to ','→', 'to'); +class To extends BinaryOperator { + init () { + super.init.call(this, '\\to ','→', 'to'); } - _.deleteTowards = function(dir, cursor) { + deleteTowards (dir, cursor) { if (dir === L) { var l = cursor[L]; new Fragment(l, this).remove(); @@ -910,9 +910,9 @@ var To = P(BinaryOperator, function(_, super_) { cursor[L].bubble(function (node) { node.reflow(); }); return; } - super_.deleteTowards.apply(this, arguments); + super.deleteTowards.apply(this, arguments); }; -}) +} LatexCmds['→'] = LatexCmds.to = To; @@ -956,7 +956,7 @@ var Greater = P(Inequality, function(_, super_) { var l = cursor[L]; cursor[L] = l[L]; l.remove(); - To().createLeftOf(cursor); + new To().createLeftOf(cursor); cursor[L].bubble(function (node) { node.reflow(); }); return; } From 6e478359f425443439d4697642e454e64bd4a4bc Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 10:18:07 -0500 Subject: [PATCH 037/192] convert Inequality to ES6 class --- src/commands/math/basicSymbols.js | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 9646e1d0d..d585ddf51 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -916,15 +916,20 @@ class To extends BinaryOperator { LatexCmds['→'] = LatexCmds.to = To; -var Inequality = P(BinaryOperator, function(_, super_) { - _.init = function(data, strict) { +class Inequality extends BinaryOperator { + constructor (data, strict) { + this.init(data,strict); + } + + init (data,strict) { this.data = data; this.strict = strict; var strictness = (strict ? 'Strict' : ''); - super_.init.call(this, data['ctrlSeq'+strictness], data['html'+strictness], + super.init.call(this, data['ctrlSeq'+strictness], data['html'+strictness], data['text'+strictness], data['mathspeak'+strictness]); - }; - _.swap = function(strict) { + } + + swap (strict) { this.strict = strict; var strictness = (strict ? 'Strict' : ''); this.ctrlSeq = this.data['ctrlSeq'+strictness]; @@ -932,15 +937,15 @@ var Inequality = P(BinaryOperator, function(_, super_) { this.textTemplate = [ this.data['text'+strictness] ]; this.mathspeakName = this.data['mathspeak'+strictness]; }; - _.deleteTowards = function(dir, cursor) { + deleteTowards (dir, cursor) { if (dir === L && !this.strict) { this.swap(true); this.bubble(function (node) { node.reflow(); }); return; } - super_.deleteTowards.apply(this, arguments); + super.deleteTowards.apply(this, arguments); }; -}); +}; var less = { ctrlSeq: '\\le ', html: '≤', text: '≤', mathspeak: 'less than or equal to', ctrlSeqStrict: '<', htmlStrict: '<', textStrict: '<', mathspeakStrict: 'less than'}; @@ -964,10 +969,10 @@ var Greater = P(Inequality, function(_, super_) { }; }) -LatexCmds['<'] = LatexCmds.lt = bind(Inequality, less, true); +LatexCmds['<'] = LatexCmds.lt = () => new Inequality(less, true); LatexCmds['>'] = LatexCmds.gt = Greater; -LatexCmds['≤'] = LatexCmds.le = LatexCmds.leq = bind(Inequality, less, false); -LatexCmds['≥'] = LatexCmds.ge = LatexCmds.geq = bind(Inequality, greater, false); +LatexCmds['≤'] = LatexCmds.le = LatexCmds.leq = () => new Inequality(less, false); +LatexCmds['≥'] = LatexCmds.ge = LatexCmds.geq = () => new Inequality(greater, false); LatexCmds.infty = LatexCmds.infin = LatexCmds.infinity = bindVanillaSymbol('\\infty ','∞', 'infinity'); LatexCmds['≠'] = LatexCmds.ne = LatexCmds.neq = bindBinaryOperator('\\ne ','≠', 'not equal'); From 407c4a19d1169b19beb6ff853dab563adc9c9f23 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 10:21:30 -0500 Subject: [PATCH 038/192] convert Greater to ES6 class --- src/commands/math/basicSymbols.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index d585ddf51..71828fd86 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -952,11 +952,14 @@ var less = { ctrlSeq: '\\le ', html: '≤', text: '≤', mathspeak: 'less than var greater = { ctrlSeq: '\\ge ', html: '≥', text: '≥', mathspeak: 'greater than or equal to', ctrlSeqStrict: '>', htmlStrict: '>', textStrict: '>', mathspeakStrict: 'greater than'}; -var Greater = P(Inequality, function(_, super_) { - _.init = function() { - super_.init.call(this, greater, true); +class Greater extends Inequality { + constructor () { + this.init(); + } + init () { + super.init.call(this, greater, true); }; - _.createLeftOf = function(cursor) { + createLeftOf (cursor) { if (cursor[L] instanceof BinaryOperator && cursor[L].ctrlSeq === '-') { var l = cursor[L]; cursor[L] = l[L]; @@ -965,9 +968,9 @@ var Greater = P(Inequality, function(_, super_) { cursor[L].bubble(function (node) { node.reflow(); }); return; } - super_.createLeftOf.apply(this, arguments); + super.createLeftOf.apply(this, arguments); }; -}) +} LatexCmds['<'] = LatexCmds.lt = () => new Inequality(less, true); LatexCmds['>'] = LatexCmds.gt = Greater; From 26f182bee6dde2f7c9e4ff679b129e677f020d31 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 10:23:54 -0500 Subject: [PATCH 039/192] convert Equality to ES6 class --- src/commands/math/basicSymbols.js | 15 +++++++++------ src/commands/math/commands.js | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 71828fd86..f73f71930 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -980,19 +980,22 @@ LatexCmds.infty = LatexCmds.infin = LatexCmds.infinity = bindVanillaSymbol('\\infty ','∞', 'infinity'); LatexCmds['≠'] = LatexCmds.ne = LatexCmds.neq = bindBinaryOperator('\\ne ','≠', 'not equal'); -var Equality = P(BinaryOperator, function(_, super_) { - _.init = function() { - super_.init.call(this, '=', '=', '=', 'equals'); +class Equality extends BinaryOperator { + constructor () { + this.init(); + } + init () { + super.init('=', '=', '=', 'equals'); }; - _.createLeftOf = function(cursor) { + createLeftOf (cursor) { if (cursor[L] instanceof Inequality && cursor[L].strict) { cursor[L].swap(false); cursor[L].bubble(function (node) { node.reflow(); }); return; } - super_.createLeftOf.apply(this, arguments); + super.createLeftOf.apply(this, arguments); }; -}); +}; LatexCmds['='] = Equality; LatexCmds['×'] = LatexCmds.times = bindBinaryOperator('\\times ', '×', '[x]', 'times'); diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 9237e58c7..00f6b5174 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -475,7 +475,7 @@ var SummationNotation = P(MathCommand, function(_, super_) { super_.createLeftOf.apply(this, arguments); if (cursor.options.sumStartsWithNEquals) { new Letter('n').createLeftOf(cursor); - Equality().createLeftOf(cursor); + new Equality().createLeftOf(cursor); } }; _.latex = function() { From 8fc43ee3e221fad72ec0e93774a2899b5ab5817f Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 10:28:05 -0500 Subject: [PATCH 040/192] convert Sim and Approx to ES6 class --- src/commands/math/basicSymbols.js | 34 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index f73f71930..a1d5b261a 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -1004,39 +1004,45 @@ LatexCmds['÷'] = LatexCmds.div = LatexCmds.divide = LatexCmds.divides = bindBinaryOperator('\\div ','÷', '[/]', 'over'); -var Sim = P(BinaryOperator, function(_, super_) { - _.init = function() { - super_.init.call(this, '\\sim ', '~', '~', 'tilde'); +class Sim extends BinaryOperator { + constructor () { + this.init(); + } + init () { + super.init('\\sim ', '~', '~', 'tilde'); }; - _.createLeftOf = function(cursor) { + createLeftOf (cursor) { if (cursor[L] instanceof Sim) { var l = cursor[L]; cursor[L] = l[L]; l.remove(); - Approx().createLeftOf(cursor); + new Approx().createLeftOf(cursor); cursor[L].bubble(function (node) { node.reflow(); }); return; } - super_.createLeftOf.apply(this, arguments); + super.createLeftOf.apply(this, arguments); }; -}); +}; -var Approx = P(BinaryOperator, function(_, super_) { - _.init = function() { - super_.init.call(this, '\\approx ', '≈', '≈', 'approximately equal'); +class Approx extends BinaryOperator { + constructor () { + this.init(); + } + init () { + super.init('\\approx ', '≈', '≈', 'approximately equal'); }; - _.deleteTowards = function(dir, cursor) { + deleteTowards (dir, cursor) { if (dir === L) { var l = cursor[L]; new Fragment(l, this).remove(); cursor[L] = l[L]; - Sim().createLeftOf(cursor); + new Sim().createLeftOf(cursor); cursor[L].bubble(function (node) { node.reflow(); }); return; } - super_.deleteTowards.apply(this, arguments); + super.deleteTowards.apply(this, arguments); }; -}); +}; CharCmds['~'] = LatexCmds.sim = Sim; LatexCmds['≈'] = LatexCmds.approx = Approx; From deb3b4be01c7598659921bae82a2a256c30b175a Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 10:36:44 -0500 Subject: [PATCH 041/192] convert Style to ES6 class --- src/commands/math/commands.js | 42 +++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 00f6b5174..50866e5f5 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -80,27 +80,31 @@ var SVG_SYMBOLS = { } }; -var Style = P(MathCommand, function(_, super_) { - _.init = function(ctrlSeq, tagName, attrs, ariaLabel, opts) { - super_.init.call(this, ctrlSeq, '<'+tagName+' '+attrs+'>&0'); - _.ariaLabel = ariaLabel || ctrlSeq.replace(/^\\/, ''); - _.mathspeakTemplate = ['Start' + _.ariaLabel + ',', 'End' + _.ariaLabel]; +class Style extends MathCommand { + constructor (ctrlSeq, tagName, attrs, ariaLabel, opts) { + this.init(ctrlSeq, tagName, attrs, ariaLabel, opts); + } + + init (ctrlSeq, tagName, attrs, ariaLabel, opts) { + super.init(ctrlSeq, '<'+tagName+' '+attrs+'>&0'); + this.ariaLabel = ariaLabel || ctrlSeq.replace(/^\\/, ''); + this.mathspeakTemplate = ['Start' + this.ariaLabel + ',', 'End' + this.ariaLabel]; // In most cases, mathspeak should announce the start and end of style blocks. // There is one exception currently (mathrm). - _.shouldNotSpeakDelimiters = opts && opts.shouldNotSpeakDelimiters; + this.shouldNotSpeakDelimiters = opts && opts.shouldNotSpeakDelimiters; }; - _.mathspeak = function(opts) { + mathspeak (opts) { if ( !this.shouldNotSpeakDelimiters || (opts && opts.ignoreShorthand) ) { - return super_.mathspeak.call(this); + return super.mathspeak.call(this); } return this.foldChildren('', function(speech, block) { return speech + ' ' + block.mathspeak(opts); }).trim(); }; -}); +}; //fonts LatexCmds.mathrm = P(Style, function(_, super_) { @@ -111,17 +115,17 @@ LatexCmds.mathrm = P(Style, function(_, super_) { return true; }; }); -LatexCmds.mathit = bind(Style, '\\mathit', 'i', 'class="mq-font"', 'Italic Font'); -LatexCmds.mathbf = bind(Style, '\\mathbf', 'b', 'class="mq-font"', 'Bold Font'); -LatexCmds.mathsf = bind(Style, '\\mathsf', 'span', 'class="mq-sans-serif mq-font"', 'Serif Font'); -LatexCmds.mathtt = bind(Style, '\\mathtt', 'span', 'class="mq-monospace mq-font"', 'Math Text'); +LatexCmds.mathit = () => new Style('\\mathit', 'i', 'class="mq-font"', 'Italic Font'); +LatexCmds.mathbf = () => new Style('\\mathbf', 'b', 'class="mq-font"', 'Bold Font'); +LatexCmds.mathsf = () => new Style('\\mathsf', 'span', 'class="mq-sans-serif mq-font"', 'Serif Font'); +LatexCmds.mathtt = () => new Style('\\mathtt', 'span', 'class="mq-monospace mq-font"', 'Math Text'); //text-decoration -LatexCmds.underline = bind(Style, '\\underline', 'span', 'class="mq-non-leaf mq-underline"', 'Underline'); -LatexCmds.overline = LatexCmds.bar = bind(Style, '\\overline', 'span', 'class="mq-non-leaf mq-overline"', 'Overline'); -LatexCmds.overrightarrow = bind(Style, '\\overrightarrow', 'span', 'class="mq-non-leaf mq-overarrow mq-arrow-right"', 'Over Right Arrow'); -LatexCmds.overleftarrow = bind(Style, '\\overleftarrow', 'span', 'class="mq-non-leaf mq-overarrow mq-arrow-left"', 'Over Left Arrow'); -LatexCmds.overleftrightarrow = bind(Style, '\\overleftrightarrow ', 'span', 'class="mq-non-leaf mq-overarrow mq-arrow-leftright"', 'Over Left and Right Arrow'); -LatexCmds.overarc = bind(Style, '\\overarc', 'span', 'class="mq-non-leaf mq-overarc"', 'Over Arc'); +LatexCmds.underline = () => new Style('\\underline', 'span', 'class="mq-non-leaf mq-underline"', 'Underline'); +LatexCmds.overline = LatexCmds.bar = () => new Style('\\overline', 'span', 'class="mq-non-leaf mq-overline"', 'Overline'); +LatexCmds.overrightarrow = () => new Style('\\overrightarrow', 'span', 'class="mq-non-leaf mq-overarrow mq-arrow-right"', 'Over Right Arrow'); +LatexCmds.overleftarrow = () => new Style('\\overleftarrow', 'span', 'class="mq-non-leaf mq-overarrow mq-arrow-left"', 'Over Left Arrow'); +LatexCmds.overleftrightarrow = () => new Style('\\overleftrightarrow ', 'span', 'class="mq-non-leaf mq-overarrow mq-arrow-leftright"', 'Over Left and Right Arrow'); +LatexCmds.overarc = () => new Style('\\overarc', 'span', 'class="mq-non-leaf mq-overarc"', 'Over Arc'); LatexCmds.dot = P(MathCommand, function(_, super_) { _.init = function() { super_.init.call(this, '\\dot', '' From 9186813d0856d383ad9d9b0a40dec807c26872a6 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 10:42:30 -0500 Subject: [PATCH 042/192] convert mathrm to ES6 class --- src/commands/math/commands.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 50866e5f5..29ac7d72d 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -107,14 +107,14 @@ class Style extends MathCommand { }; //fonts -LatexCmds.mathrm = P(Style, function(_, super_) { - _.init = function() { - super_.init.call(this, '\\mathrm', 'span', 'class="mq-roman mq-font"', 'Roman Font', { shouldNotSpeakDelimiters: true }); +LatexCmds.mathrm = class extends Style { + init () { + super.init('\\mathrm', 'span', 'class="mq-roman mq-font"', 'Roman Font', { shouldNotSpeakDelimiters: true }); }; - _.isTextBlock = function() { + isTextBlock () { return true; }; -}); +}; LatexCmds.mathit = () => new Style('\\mathit', 'i', 'class="mq-font"', 'Italic Font'); LatexCmds.mathbf = () => new Style('\\mathbf', 'b', 'class="mq-font"', 'Bold Font'); LatexCmds.mathsf = () => new Style('\\mathsf', 'span', 'class="mq-sans-serif mq-font"', 'Serif Font'); From 18347c3f3a8c961d65c1a5e1c7f0673413714131 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 10:44:43 -0500 Subject: [PATCH 043/192] convert dot to ES6 class --- src/commands/math/commands.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 29ac7d72d..c6b57d8dd 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -126,15 +126,14 @@ LatexCmds.overrightarrow = () => new Style('\\overrightarrow', 'span', 'class="m LatexCmds.overleftarrow = () => new Style('\\overleftarrow', 'span', 'class="mq-non-leaf mq-overarrow mq-arrow-left"', 'Over Left Arrow'); LatexCmds.overleftrightarrow = () => new Style('\\overleftrightarrow ', 'span', 'class="mq-non-leaf mq-overarrow mq-arrow-leftright"', 'Over Left and Right Arrow'); LatexCmds.overarc = () => new Style('\\overarc', 'span', 'class="mq-non-leaf mq-overarc"', 'Over Arc'); -LatexCmds.dot = P(MathCommand, function(_, super_) { - _.init = function() { - super_.init.call(this, '\\dot', '' +LatexCmds.dot = () => { + return new MathCommand('\\dot', '' + '˙' + '&0' + '' ); - }; -}); +}; + // `\textcolor{color}{math}` will apply a color to the given math content, where // `color` is any valid CSS Color Value (see [SitePoint docs][] (recommended), From 9c6bf37c83459c98956cf59a263df8e782a6a9cc Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 10:54:31 -0500 Subject: [PATCH 044/192] convert textcolor to ES6 class --- src/commands/math/commands.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index c6b57d8dd..849f272f2 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -142,19 +142,18 @@ LatexCmds.dot = () => { // [SitePoint docs]: http://reference.sitepoint.com/css/colorvalues // [Mozilla docs]: https://developer.mozilla.org/en-US/docs/CSS/color_value#Values // [W3C spec]: http://dev.w3.org/csswg/css3-color/#colorunits -var TextColor = LatexCmds.textcolor = P(MathCommand, function(_, super_) { - _.setColor = function(color) { +LatexCmds.textcolor = class extends MathCommand { + setColor (color) { this.color = color; this.htmlTemplate = '&0'; - _.ariaLabel = color.replace(/^\\/, ''); - _.mathspeakTemplate = ['Start ' + _.ariaLabel + ',', 'End ' + _.ariaLabel]; + this.ariaLabel = color.replace(/^\\/, ''); + this.mathspeakTemplate = ['Start ' + this.ariaLabel + ',', 'End ' + this.ariaLabel]; }; - _.latex = function() { + latex () { return '\\textcolor{' + this.color + '}{' + this.blocks[0].latex() + '}'; }; - _.parser = function() { - var self = this; + parser () { var optWhitespace = Parser.optWhitespace; var string = Parser.string; var regex = Parser.regex; @@ -163,16 +162,16 @@ var TextColor = LatexCmds.textcolor = P(MathCommand, function(_, super_) { .then(string('{')) .then(regex(/^[#\w\s.,()%-]*/)) .skip(string('}')) - .then(function(color) { - self.setColor(color); - return super_.parser.call(self); + .then((color) => { + this.setColor(color); + return super.parser(); }) ; }; - _.isStyleBlock = function() { + isStyleBlock () { return true; }; -}); +}; // Very similar to the \textcolor command, but will add the given CSS class. // Usage: \class{classname}{math} From 57618b61eb30613b6dc01cf1ec283bc04fd98683 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 10:58:38 -0500 Subject: [PATCH 045/192] convert ans and percentof to ES6 class --- src/commands/math/commands.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 849f272f2..1b480de89 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -699,27 +699,18 @@ CharCmds['/'] = P(Fraction, function(_, super_) { }; }); -LatexCmds.ans = P(Symbol, function(_, super_) { - _.init = function(ch) { - super_.init.call(this, +LatexCmds.ans = () => new Symbol( '\\operatorname{ans}', 'ans', 'ans' ); - }; -}); LatexCmds.percent = -LatexCmds.percentof = P(Symbol, function (_, super_) { - _.init = function () { - super_.init.call( - this, +LatexCmds.percentof = () => new Symbol( '\\%\\operatorname{of}', '% of ', 'percent of' ) - }; -}); var SquareRoot = LatexCmds.sqrt = P(MathCommand, function(_, super_) { From 2699ad0da2d8324f537a514a56e21890948fed10 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 11:39:40 -0500 Subject: [PATCH 046/192] convert LatexCmds.class to ES6 class --- src/commands/math/commands.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 1b480de89..cd036b06e 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -177,29 +177,29 @@ LatexCmds.textcolor = class extends MathCommand { // Usage: \class{classname}{math} // Note regex that whitelists valid CSS classname characters: // https://github.com/mathquill/mathquill/pull/191#discussion_r4327442 -var Class = LatexCmds['class'] = P(MathCommand, function(_, super_) { - _.parser = function() { - var self = this, string = Parser.string, regex = Parser.regex; +var Class = LatexCmds['class'] = class extends MathCommand { + parser () { + var string = Parser.string, regex = Parser.regex; return Parser.optWhitespace .then(string('{')) .then(regex(/^[-\w\s\\\xA0-\xFF]*/)) .skip(string('}')) - .then(function(cls) { - self.cls = cls || ''; - self.htmlTemplate = '&0'; - self.ariaLabel = cls + ' class'; - self.mathspeakTemplate = ['Start ' + self.ariaLabel + ',', 'End ' + self.ariaLabel]; - return super_.parser.call(self); + .then((cls) => { + this.cls = cls || ''; + this.htmlTemplate = '&0'; + this.ariaLabel = cls + ' class'; + this.mathspeakTemplate = ['Start ' + this.ariaLabel + ',', 'End ' + this.ariaLabel]; + return super.parser(); }) ; }; - _.latex = function() { + latex () { return '\\class{' + this.cls + '}{' + this.blocks[0].latex() + '}'; }; - _.isStyleBlock = function() { + isStyleBlock () { return true; }; -}); +}; // This test is used to determine whether an item may be treated as a whole number // for shortening the verbalized (mathspeak) forms of some fractions and superscripts. From 1eb8f951c46a1fbde1dd238ebe331011a5daadce Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 11:48:02 -0500 Subject: [PATCH 047/192] convert SupSub to ES6 class --- src/commands/math/commands.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index cd036b06e..d1ef91fb8 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -223,13 +223,17 @@ function getCtrlSeqsFromBlock(block) { return chars; } -var SupSub = P(MathCommand, function(_, super_) { - _.ctrlSeq = '_{...}^{...}'; - _.createLeftOf = function(cursor) { +Options.p.charsThatBreakOutOfSupSub = ''; + +class SupSub extends MathCommand { + static _todoMoveIntoConstructor = + SupSub.prototype.ctrlSeq = '_{...}^{...}'; + + createLeftOf (cursor) { if (!this.replacedFragment && !cursor[L] && cursor.options.supSubsRequireOperand) return; - return super_.createLeftOf.apply(this, arguments); + return super.createLeftOf.apply(this, arguments); }; - _.contactWeld = function(cursor) { + contactWeld (cursor) { // Look on either side for a SupSub, if one is found compare my // .sub, .sup with its .sub, .sup. If I have one that it doesn't, // then call .addBlock() on it with my block; if I have one that @@ -270,8 +274,7 @@ var SupSub = P(MathCommand, function(_, super_) { } } }; - Options.p.charsThatBreakOutOfSupSub = ''; - _.finalizeTree = function() { + finalizeTree () { this.ends[L].write = function(cursor, ch) { if (cursor.options.autoSubscriptNumerals && this === this.parent.sub) { if (ch === '_') return; @@ -290,13 +293,13 @@ var SupSub = P(MathCommand, function(_, super_) { MathBlock.prototype.write.apply(this, arguments); }; }; - _.moveTowards = function(dir, cursor, updown) { + moveTowards (dir, cursor, updown) { if (cursor.options.autoSubscriptNumerals && !this.sup) { cursor.insDirOf(dir, this); } - else super_.moveTowards.apply(this, arguments); + else super.moveTowards.apply(this, arguments); }; - _.deleteTowards = function(dir, cursor) { + deleteTowards (dir, cursor) { if (cursor.options.autoSubscriptNumerals && this.sub) { var cmd = this.sub.ends[-dir]; if (cmd instanceof Symbol) cmd.remove(); @@ -311,23 +314,23 @@ var SupSub = P(MathCommand, function(_, super_) { // `dir` (try it), the cursor appears to have gone "through" the ^2. } } - else super_.deleteTowards.apply(this, arguments); + else super.deleteTowards.apply(this, arguments); }; - _.latex = function() { + latex () { function latex(prefix, block) { var l = block && block.latex(); return block ? prefix + '{' + (l || ' ') + '}' : ''; } return latex('_', this.sub) + latex('^', this.sup); }; - _.text = function() { + text () { function text(prefix, block) { var l = block && block.text(); return block ? prefix + (l.length === 1 ? l : '(' + (l || ' ') + ')') : ''; } return text('_', this.sub) + text('^', this.sup); }; - _.addBlock = function(block) { + addBlock (block) { if (this.supsub === 'sub') { this.sup = this.upInto = this.sub.upOutOf = block; block.adopt(this, this.sub, 0).downOutOf = this.sub; @@ -365,7 +368,7 @@ var SupSub = P(MathCommand, function(_, super_) { }; }(this, 'sub sup'.split(' ')[i], 'sup sub'.split(' ')[i], 'down up'.split(' ')[i])); }; -}); +}; function insLeftOfMeUnlessAtEnd(cursor) { // cursor.insLeftOf(cmd), unless cursor at the end of block, and every From 7f1dc32e557276fd8c5cc6a1f3c3dfe526b4dcf6 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 13:08:48 -0500 Subject: [PATCH 048/192] convert LatexCmds._ to ES6 class --- src/commands/math/basicSymbols.js | 2 +- src/commands/math/commands.js | 28 ++++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index a1d5b261a..89192c205 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -170,7 +170,7 @@ class Digit extends DigitGroupingChar { || (cursor[L] instanceof SupSub && cursor[L][L] instanceof Variable && cursor[L][L].isItalic !== false))) { - LatexCmds._().createLeftOf(cursor); + new LatexCmds._().createLeftOf(cursor); super.createLeftOf.call(this, cursor); cursor.insRightOf(cursor.parent.parent); } diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index d1ef91fb8..4bd6ba88e 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -382,23 +382,31 @@ function insLeftOfMeUnlessAtEnd(cursor) { } LatexCmds.subscript = -LatexCmds._ = P(SupSub, function(_, super_) { - _.supsub = 'sub'; - _.htmlTemplate = +LatexCmds._ = class SubscriptCommand extends SupSub { + static _todoMoveIntoConstructor = + SubscriptCommand.prototype.supsub = 'sub'; + static _todoMoveIntoConstructor = + SubscriptCommand.prototype.htmlTemplate = '' + '&0' + '' + '' - ; - _.textTemplate = [ '_' ]; - _.mathspeakTemplate = [ 'Subscript,', ', Baseline']; - _.ariaLabel = 'subscript'; - _.finalizeTree = function() { + + static _todoMoveIntoConstructor = + SubscriptCommand.prototype.textTemplate = [ '_' ]; + + static _todoMoveIntoConstructor = + SubscriptCommand.prototype.mathspeakTemplate = [ 'Subscript,', ', Baseline']; + + static _todoMoveIntoConstructor = + SubscriptCommand.prototype.ariaLabel = 'subscript'; + + finalizeTree () { this.downInto = this.sub = this.ends[L]; this.sub.upOutOf = insLeftOfMeUnlessAtEnd; - super_.finalizeTree.call(this); + super.finalizeTree() }; -}); +}; LatexCmds.superscript = LatexCmds.supscript = From 468ce6d52b2f92afad8dd5e661795abbafb4ec95 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 13:42:35 -0500 Subject: [PATCH 049/192] convert LatexCmds[^] to ES6 class --- src/commands/math/commands.js | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 4bd6ba88e..6eec1f8ae 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -410,15 +410,18 @@ LatexCmds._ = class SubscriptCommand extends SupSub { LatexCmds.superscript = LatexCmds.supscript = -LatexCmds['^'] = P(SupSub, function(_, super_) { - _.supsub = 'sup'; - _.htmlTemplate = +LatexCmds['^'] = class SuperscriptCommand extends SupSub { + static _todoMoveIntoConstructor = + SuperscriptCommand.prototype.supsub = 'sup'; + static _todoMoveIntoConstructor = + SuperscriptCommand.prototype.htmlTemplate = '' + '&0' + '' ; - _.textTemplate = ['^(', ')']; - _.mathspeak = function(opts) { + static _todoMoveIntoConstructor = + SuperscriptCommand.prototype.textTemplate = ['^(', ')']; + mathspeak (opts) { // Simplify basic exponent speech for common whole numbers. var child = this.upInto; if (child !== undefined) { @@ -460,17 +463,19 @@ LatexCmds['^'] = P(SupSub, function(_, super_) { return 'to the ' + innerMathspeak + suffix + ' power'; } } - return super_.mathspeak.call(this); + return super.mathspeak(); }; - _.ariaLabel = 'superscript'; - _.mathspeakTemplate = [ 'Superscript,', ', Baseline']; - _.finalizeTree = function() { + static _todoMoveIntoConstructor = + SuperscriptCommand.prototype.ariaLabel = 'superscript'; + static _todoMoveIntoConstructor = + SuperscriptCommand.prototype.mathspeakTemplate = [ 'Superscript,', ', Baseline']; + finalizeTree () { this.upInto = this.sup = this.ends[R]; this.sup.downOutOf = insLeftOfMeUnlessAtEnd; - super_.finalizeTree.call(this); + super.finalizeTree(); }; -}); +}; var SummationNotation = P(MathCommand, function(_, super_) { _.init = function(ch, html, ariaLabel) { From 999a2d341f2ce863ebde33ab5e58fd969ee7adaa Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 13:49:21 -0500 Subject: [PATCH 050/192] convert SummationNotation to ES6 class --- src/commands/math/commands.js | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 6eec1f8ae..067575b41 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -477,9 +477,13 @@ LatexCmds['^'] = class SuperscriptCommand extends SupSub { }; }; -var SummationNotation = P(MathCommand, function(_, super_) { - _.init = function(ch, html, ariaLabel) { - _.ariaLabel = ariaLabel || ctrlSeq.replace(/^\\/, ''); +class SummationNotation extends MathCommand { + constructor (ch, html, ariaLabel) { + this.init(ch, html, ariaLabel) + } + + init (ch, html, ariaLabel) { + this.ariaLabel = ariaLabel || ctrlSeq.replace(/^\\/, ''); var htmlTemplate = '' + '&1' @@ -489,25 +493,25 @@ var SummationNotation = P(MathCommand, function(_, super_) { ; Symbol.prototype.init.call(this, ch, htmlTemplate); }; - _.createLeftOf = function(cursor) { - super_.createLeftOf.apply(this, arguments); + createLeftOf (cursor) { + super.createLeftOf.apply(this, arguments); if (cursor.options.sumStartsWithNEquals) { new Letter('n').createLeftOf(cursor); new Equality().createLeftOf(cursor); } }; - _.latex = function() { + latex () { function simplify(latex) { return '{' + (latex || ' ') + '}'; } return this.ctrlSeq + '_' + simplify(this.ends[L].latex()) + '^' + simplify(this.ends[R].latex()); }; - _.mathspeak = function() { + mathspeak () { return 'Start ' + this.ariaLabel + ' from ' + this.ends[L].mathspeak() + ' to ' + this.ends[R].mathspeak() + ', end ' + this.ariaLabel + ', '; }; - _.parser = function() { + parser () { var string = Parser.string; var optWhitespace = Parser.optWhitespace; var succeed = Parser.succeed; @@ -527,7 +531,7 @@ var SummationNotation = P(MathCommand, function(_, super_) { }); }).many().result(self); }; - _.finalizeTree = function() { + finalizeTree () { this.ends[L].ariaLabel = 'lower bound'; this.ends[R].ariaLabel = 'upper bound'; this.downInto = this.ends[L]; @@ -535,18 +539,18 @@ var SummationNotation = P(MathCommand, function(_, super_) { this.ends[L].upOutOf = this.ends[R]; this.ends[R].downOutOf = this.ends[L]; }; -}); +}; LatexCmds['∑'] = LatexCmds.sum = -LatexCmds.summation = bind(SummationNotation,'\\sum ','∑', 'sum'); +LatexCmds.summation = () => new SummationNotation('\\sum ','∑', 'sum'); LatexCmds['∏'] = LatexCmds.prod = -LatexCmds.product = bind(SummationNotation,'\\prod ','∏', 'product'); +LatexCmds.product = () => new SummationNotation('\\prod ','∏', 'product'); LatexCmds.coprod = -LatexCmds.coproduct = bind(SummationNotation,'\\coprod ','∐', 'co product'); +LatexCmds.coproduct = () => new SummationNotation('\\coprod ','∐', 'co product'); LatexCmds['∫'] = LatexCmds['int'] = From 33193123231a70489981121c4b88b7845f696c11 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 13:54:15 -0500 Subject: [PATCH 051/192] convert LatexCommands.int to ES6 class --- src/commands/math/commands.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 067575b41..712c42449 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -554,9 +554,9 @@ LatexCmds.coproduct = () => new SummationNotation('\\coprod ','∐', 'co pro LatexCmds['∫'] = LatexCmds['int'] = -LatexCmds.integral = P(SummationNotation, function(_, super_) { - _.init = function() { - _.ariaLabel = 'integral'; +LatexCmds.integral = class extends SummationNotation { + init () { + this.ariaLabel = 'integral'; var htmlTemplate = '' + '' @@ -569,9 +569,12 @@ LatexCmds.integral = P(SummationNotation, function(_, super_) { ; Symbol.prototype.init.call(this, '\\int ', htmlTemplate, 'integral'); }; - // FIXME: refactor rather than overriding - _.createLeftOf = MathCommand.prototype.createLeftOf; -}); + + createLeftOf (cursor) { + // FIXME: refactor rather than overriding + MathCommand.prototype.createLeftOf.call(this, cursor); + } +}; var Fraction = LatexCmds.frac = LatexCmds.dfrac = From d23034b7b077ade9e5b4f891d88324698caa3b72 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 13:57:43 -0500 Subject: [PATCH 052/192] convert Frac to ES6 class --- src/commands/math/commands.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 712c42449..3261b1592 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -579,17 +579,20 @@ var Fraction = LatexCmds.frac = LatexCmds.dfrac = LatexCmds.cfrac = -LatexCmds.fraction = P(MathCommand, function(_, super_) { - _.ctrlSeq = '\\frac'; - _.htmlTemplate = +LatexCmds.fraction = class FracNode extends MathCommand { + static _todoMoveIntoConstructor = + FracNode.prototype.ctrlSeq = '\\frac'; + static _todoMoveIntoConstructor = + FracNode.prototype.htmlTemplate = '' + '&0' + '&1' + '' + '' ; - _.textTemplate = ['(', ')/(', ')']; - _.finalizeTree = function() { + static _todoMoveIntoConstructor = + FracNode.prototype.textTemplate = ['(', ')/(', ')']; + finalizeTree () { this.upInto = this.ends[R].upOutOf = this.ends[L]; this.downInto = this.ends[L].downOutOf = this.ends[R]; this.ends[L].ariaLabel = 'numerator'; @@ -601,7 +604,7 @@ LatexCmds.fraction = P(MathCommand, function(_, super_) { } }; - _.mathspeak = function(opts) { + mathspeak (opts) { if (opts && opts.createdLeftOf) { var cursor = opts.createdLeftOf; return cursor.parent.mathspeak(); @@ -675,10 +678,10 @@ LatexCmds.fraction = P(MathCommand, function(_, super_) { } } - return super_.mathspeak.apply(this, arguments); + return super.mathspeak.apply(this, arguments); }; - _.getFracDepth = function() { + getFracDepth () { var level = 0; var walkUp = function(item, level) { if(item instanceof Node && item.ctrlSeq && item.ctrlSeq.toLowerCase().search('frac') >= 0) level += 1; @@ -687,7 +690,7 @@ LatexCmds.fraction = P(MathCommand, function(_, super_) { }; return walkUp(this, level); }; -}); +}; var LiveFraction = LatexCmds.over = From 3fe5e0b1481b44e6ed9be244a455d5722872da09 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 13:59:04 -0500 Subject: [PATCH 053/192] convert LatexCmds[/] to ES6 class --- src/commands/math/commands.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 3261b1592..03f588ec9 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -694,8 +694,8 @@ LatexCmds.fraction = class FracNode extends MathCommand { var LiveFraction = LatexCmds.over = -CharCmds['/'] = P(Fraction, function(_, super_) { - _.createLeftOf = function(cursor) { +CharCmds['/'] = class extends Fraction { + createLeftOf (cursor) { if (!this.replacedFragment) { var leftward = cursor[L]; @@ -721,9 +721,9 @@ CharCmds['/'] = P(Fraction, function(_, super_) { cursor[L] = leftward; } } - super_.createLeftOf.call(this, cursor); + super.createLeftOf.call(this, cursor); }; -}); +}; LatexCmds.ans = () => new Symbol( '\\operatorname{ans}', From 06a0da8981b16ecd8c1b726a46c500ed371977ab Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 14:08:31 -0500 Subject: [PATCH 054/192] convert SquareRoot to ES6 class --- src/commands/math/commands.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 03f588ec9..e6f888cf1 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -738,10 +738,11 @@ LatexCmds.percentof = () => new Symbol( 'percent of' ) -var SquareRoot = -LatexCmds.sqrt = P(MathCommand, function(_, super_) { - _.ctrlSeq = '\\sqrt'; - _.htmlTemplate = +class SquareRoot extends MathCommand { + static _todoMoveIntoConstructor = + SquareRoot.prototype.ctrlSeq = '\\sqrt'; + static _todoMoveIntoConstructor = + SquareRoot.prototype.htmlTemplate = '' + '' + SVG_SYMBOLS.sqrt.html @@ -749,10 +750,13 @@ LatexCmds.sqrt = P(MathCommand, function(_, super_) { + '&0' + '' ; - _.textTemplate = ['sqrt(', ')']; - _.mathspeakTemplate = ['StartRoot,', ', EndRoot']; - _.ariaLabel = 'root'; - _.parser = function() { + static _todoMoveIntoConstructor = + SquareRoot.prototype.textTemplate = ['sqrt(', ')']; + static _todoMoveIntoConstructor = + SquareRoot.prototype.mathspeakTemplate = ['StartRoot,', ', EndRoot']; + static _todoMoveIntoConstructor = + SquareRoot.prototype.ariaLabel = 'root'; + parser () { return latexMathParser.optBlock.then(function(optBlock) { return latexMathParser.block.map(function(block) { var nthroot = NthRoot(); @@ -761,9 +765,10 @@ LatexCmds.sqrt = P(MathCommand, function(_, super_) { block.adopt(nthroot, optBlock, 0); return nthroot; }); - }).or(super_.parser.call(this)); + }).or(super.parser.call(this)); }; -}); +}; +LatexCmds.sqrt = SquareRoot; var Hat = LatexCmds.hat = P(MathCommand, function(_, super_) { _.ctrlSeq = '\\hat'; From 0db189b62aeeef3e3485f3a13d6e01d978534693 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 14:10:22 -0500 Subject: [PATCH 055/192] convert Hat to ES6 class --- src/commands/math/commands.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index e6f888cf1..75fb449c3 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -770,16 +770,19 @@ class SquareRoot extends MathCommand { }; LatexCmds.sqrt = SquareRoot; -var Hat = LatexCmds.hat = P(MathCommand, function(_, super_) { - _.ctrlSeq = '\\hat'; - _.htmlTemplate = +LatexCmds.hat = class Hat extends MathCommand { + static _todoMoveIntoConstructor = + Hat.prototype.ctrlSeq = '\\hat'; + static _todoMoveIntoConstructor = + Hat.prototype.htmlTemplate = '' + '^' + '&0' + '' ; - _.textTemplate = ['hat(', ')']; -}); + static _todoMoveIntoConstructor = + Hat.prototype.textTemplate = ['hat(', ')']; +}; var NthRoot = LatexCmds.nthroot = P(SquareRoot, function(_, super_) { From 533e59426ba5afbf835e9b300269fa2fe0450cf9 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 14:13:01 -0500 Subject: [PATCH 056/192] convert Nthroot to ES6 class --- src/commands/math/commands.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 75fb449c3..729100018 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -759,7 +759,7 @@ class SquareRoot extends MathCommand { parser () { return latexMathParser.optBlock.then(function(optBlock) { return latexMathParser.block.map(function(block) { - var nthroot = NthRoot(); + var nthroot = new NthRoot(); nthroot.blocks = [ optBlock, block ]; optBlock.adopt(nthroot, 0, 0); block.adopt(nthroot, optBlock, 0); @@ -784,9 +784,9 @@ LatexCmds.hat = class Hat extends MathCommand { Hat.prototype.textTemplate = ['hat(', ')']; }; -var NthRoot = -LatexCmds.nthroot = P(SquareRoot, function(_, super_) { - _.htmlTemplate = +class NthRoot extends SquareRoot { + static _todoMoveIntoConstructor = + NthRoot.prototype.htmlTemplate = '' + '&0' + '' @@ -797,11 +797,12 @@ LatexCmds.nthroot = P(SquareRoot, function(_, super_) { + '' + '' ; - _.textTemplate = ['sqrt[', '](', ')']; - _.latex = function() { + static _todoMoveIntoConstructor = + NthRoot.prototype.textTemplate = ['sqrt[', '](', ')']; + latex () { return '\\sqrt['+this.ends[L].latex()+']{'+this.ends[R].latex()+'}'; }; - _.mathspeak = function() { + mathspeak () { var indexMathspeak = this.ends[L].mathspeak(); var radicandMathspeak = this.ends[R].mathspeak(); this.ends[L].ariaLabel = 'Index'; @@ -812,7 +813,8 @@ LatexCmds.nthroot = P(SquareRoot, function(_, super_) { return 'Root Index '+indexMathspeak+', Start Root, '+radicandMathspeak+', End Root'; } }; -}); +}; +LatexCmds.nthroot = NthRoot; var CubeRoot = LatexCmds.cbrt = P(NthRoot, function(_, super_) { From fca4eebbc998c0f256b02f28ff61931f664df719 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 14:14:19 -0500 Subject: [PATCH 057/192] convert cbrt to ES6 class --- src/commands/math/commands.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 729100018..03bf2a5e6 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -816,14 +816,13 @@ class NthRoot extends SquareRoot { }; LatexCmds.nthroot = NthRoot; -var CubeRoot = -LatexCmds.cbrt = P(NthRoot, function(_, super_) { - _.createLeftOf = function(cursor) { - super_.createLeftOf.apply(this, arguments); +LatexCmds.cbrt = class extends NthRoot { + createLeftOf (cursor) { + super.createLeftOf.apply(this, arguments); new Digit('3').createLeftOf(cursor); cursor.controller.moveRight(); }; -}); +}; var DiacriticAbove = P(MathCommand, function(_, super_) { _.init = function(ctrlSeq, symbol, textTemplate) { From 593bcb901b202bf1121be72b28ea1fafbda5e65b Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 14:16:50 -0500 Subject: [PATCH 058/192] convert DiacriticAbov to ES6 class --- src/commands/math/commands.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 03bf2a5e6..5ae22594d 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -824,8 +824,11 @@ LatexCmds.cbrt = class extends NthRoot { }; }; -var DiacriticAbove = P(MathCommand, function(_, super_) { - _.init = function(ctrlSeq, symbol, textTemplate) { +class DiacriticAbove extends MathCommand { + constructor (ctrlSeq, symbol, textTemplate) { + this.init(ctrlSeq, symbol, textTemplate); + } + init (ctrlSeq, symbol, textTemplate) { var htmlTemplate = '' + ''+symbol+'' @@ -833,11 +836,11 @@ var DiacriticAbove = P(MathCommand, function(_, super_) { + '' ; - super_.init.call(this, ctrlSeq, htmlTemplate, textTemplate); + super.init(ctrlSeq, htmlTemplate, textTemplate); }; -}); -LatexCmds.vec = bind(DiacriticAbove, '\\vec', '→', ['vec(', ')']); -LatexCmds.tilde = bind(DiacriticAbove, '\\tilde', '~', ['tilde(', ')']); +}; +LatexCmds.vec = () => new DiacriticAbove('\\vec', '→', ['vec(', ')']); +LatexCmds.tilde = () => new DiacriticAbove('\\tilde', '~', ['tilde(', ')']); function DelimsMixin(_, super_) { _.jQadd = function() { From 37b787bc88a404428bb505e7066b02022fc1af95 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 15:31:57 -0500 Subject: [PATCH 059/192] convert Embed to ES6 class --- src/commands/math/commands.js | 8 ++++---- src/publicapi.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 5ae22594d..49cef9e4c 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -1184,15 +1184,15 @@ LatexCmds.MathQuillMathField = P(MathCommand, function(_, super_) { // Create by calling public API method .dropEmbedded(), // or by calling the global public API method .registerEmbed() // and rendering LaTeX like \embed{registeredName} (see test). -var Embed = LatexCmds.embed = P(Symbol, function(_, super_) { - _.setOptions = function(options) { +LatexCmds.embed = class extends Symbol { + setOptions (options) { function noop () { return ""; } this.text = options.text || noop; this.htmlTemplate = options.htmlString || ""; this.latex = options.latex || noop; return this; }; - _.parser = function() { + parser () { var self = this, string = Parser.string, regex = Parser.regex, succeed = Parser.succeed; return string('{').then(regex(/^[a-z][a-z0-9]*/i)).skip(string('}')) @@ -1207,4 +1207,4 @@ var Embed = LatexCmds.embed = P(Symbol, function(_, super_) { }) ; }; -}); +}; diff --git a/src/publicapi.js b/src/publicapi.js index 3253b2c5b..1157ce420 100644 --- a/src/publicapi.js +++ b/src/publicapi.js @@ -231,7 +231,7 @@ function getInterface(v) { var el = document.elementFromPoint(clientX, clientY); this.__controller.seek($(el), pageX, pageY); - var cmd = Embed().setOptions(options); + var cmd = new LatexCmds.embed().setOptions(options); cmd.createLeftOf(this.__controller.cursor); }; _.setAriaLabel = function(ariaLabel) { From bcf44edba99880173e63b90cb00028992c512119 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 15:33:55 -0500 Subject: [PATCH 060/192] convert LatexCmds.left and right to ES6 class --- src/commands/math/commands.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 49cef9e4c..754c4d57e 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -1077,8 +1077,8 @@ LatexCmds.lVert = bind(Bracket, L, '∥', '∥', '\\lVert ', '\\rVert ') LatexCmds.rVert = bind(Bracket, R, '∥', '∥', '\\lVert ', '\\rVert '); -LatexCmds.left = P(MathCommand, function(_) { - _.parser = function() { +LatexCmds.left = class extends MathCommand { + parser () { var regex = Parser.regex; var string = Parser.string; var succeed = Parser.succeed; @@ -1105,13 +1105,13 @@ LatexCmds.left = P(MathCommand, function(_) { }) ; }; -}); +}; -LatexCmds.right = P(MathCommand, function(_) { - _.parser = function() { +LatexCmds.right = class extends MathCommand { + parser () { return Parser.fail('unmatched \\right'); }; -}); +}; var Binomial = LatexCmds.binom = From 8c57075dad4fa25b0b7cdf3be6a0f211d1a17d7c Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 15:39:31 -0500 Subject: [PATCH 061/192] convert MathQuillMathField to ES6 class --- src/commands/math/commands.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 754c4d57e..52070f632 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -1147,21 +1147,23 @@ LatexCmds.choose = P(Binomial, function(_) { }); LatexCmds.editable = // backcompat with before cfd3620 on #233 -LatexCmds.MathQuillMathField = P(MathCommand, function(_, super_) { - _.ctrlSeq = '\\MathQuillMathField'; - _.htmlTemplate = +LatexCmds.MathQuillMathField = class MathFieldNode extends MathCommand { + static _todoMoveIntoConstructor = + MathFieldNode.prototype.ctrlSeq = '\\MathQuillMathField'; + static _todoMoveIntoConstructor = + MathFieldNode.prototype.htmlTemplate = '' + '&0' + '' ; - _.parser = function() { + parser () { var self = this, string = Parser.string, regex = Parser.regex, succeed = Parser.succeed; return string('[').then(regex(/^[a-z][a-z0-9]*/i)).skip(string(']')) .map(function(name) { self.name = name; }).or(succeed()) - .then(super_.parser.call(self)); + .then(super.parser.call(self)); }; - _.finalizeTree = function(options) { + finalizeTree (options) { var ctrlr = Controller(this.ends[L], this.jQ, options); ctrlr.KIND_OF_MQ = 'MathField'; ctrlr.editable = true; @@ -1170,12 +1172,12 @@ LatexCmds.MathQuillMathField = P(MathCommand, function(_, super_) { ctrlr.cursor.insAtRightEnd(ctrlr.root); RootBlockMixin(ctrlr.root); }; - _.registerInnerField = function(innerFields, MathField) { + registerInnerField (innerFields, MathField) { innerFields.push(innerFields[this.name] = MathField(this.ends[L].controller)); }; - _.latex = function(){ return this.ends[L].latex(); }; - _.text = function(){ return this.ends[L].text(); }; -}); + latex (){ return this.ends[L].latex(); }; + text (){ return this.ends[L].text(); }; +}; // Embed arbitrary things // Probably the closest DOM analogue would be an iframe? From 3adaf316f409312f0a5584457998579b11044959 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 15:57:43 -0500 Subject: [PATCH 062/192] convert Bracket to ES6 class --- src/commands/math/commands.js | 72 ++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 52070f632..59df74d99 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -842,6 +842,14 @@ class DiacriticAbove extends MathCommand { LatexCmds.vec = () => new DiacriticAbove('\\vec', '→', ['vec(', ')']); LatexCmds.tilde = () => new DiacriticAbove('\\tilde', '~', ['tilde(', ')']); +class DelimsNode extends MathCommand { + jQadd (el) { + super.jQadd(el); + this.delimjQs = this.jQ.children(':first').add(this.jQ.children(':last')); + this.contentjQ = this.jQ.children(':eq(1)'); + }; +} + function DelimsMixin(_, super_) { _.jQadd = function() { super_.jQadd.apply(this, arguments); @@ -853,16 +861,20 @@ function DelimsMixin(_, super_) { // Round/Square/Curly/Angle Brackets (aka Parens/Brackets/Braces) // first typed as one-sided bracket with matching "ghost" bracket at // far end of current block, until you type an opposing one -var Bracket = P(P(MathCommand, DelimsMixin), function(_, super_) { - _.init = function(side, open, close, ctrlSeq, end) { - super_.init.call(this, '\\left'+ctrlSeq, undefined, [open, close]); +class Bracket extends DelimsNode { + constructor (side, open, close, ctrlSeq, end) { + this.init(side, open, close, ctrlSeq, end) + } + + init (side, open, close, ctrlSeq, end) { + super.init('\\left'+ctrlSeq, undefined, [open, close]); this.side = side; this.sides = {}; this.sides[L] = { ch: open, ctrlSeq: ctrlSeq }; this.sides[R] = { ch: close, ctrlSeq: end }; }; - _.numBlocks = function() { return 1; }; - _.html = function() { + numBlocks () { return 1; }; + html () { var leftSymbol = this.getSymbol(L); var rightSymbol = this.getSymbol(R); @@ -878,15 +890,15 @@ var Bracket = P(P(MathCommand, DelimsMixin), function(_, super_) { + '' + '' ; - return super_.html.call(this); + return super.html(); }; - _.getSymbol = function (side) { + getSymbol (side) { return SVG_SYMBOLS[this.sides[side || R].ch] || {width: '0', html: ''}; }; - _.latex = function() { + latex () { return '\\left'+this.sides[L].ctrlSeq+this.ends[L].latex()+'\\right'+this.sides[R].ctrlSeq; }; - _.mathspeak = function(opts) { + mathspeak (opts) { var open = this.sides[L].ch, close = this.sides[R].ch; if (open === '|' && close === '|') { this.mathspeakTemplate = ['StartAbsoluteValue,', ', EndAbsoluteValue']; @@ -902,23 +914,23 @@ var Bracket = P(P(MathCommand, DelimsMixin), function(_, super_) { this.mathspeakTemplate = ['left ' + BRACKET_NAMES[open]+',', ', right ' + BRACKET_NAMES[close]]; this.ariaLabel = BRACKET_NAMES[open]+' block'; } - return super_.mathspeak.call(this); + return super.mathspeak(); }; - _.matchBrack = function(opts, expectedSide, node) { + matchBrack (opts, expectedSide, node) { // return node iff it's a matching 1-sided bracket of expected side (if any) return node instanceof Bracket && node.side && node.side !== -expectedSide && (!opts.restrictMismatchedBrackets || OPP_BRACKS[this.sides[this.side].ch] === node.sides[node.side].ch || { '(': ']', '[': ')' }[this.sides[L].ch] === node.sides[R].ch) && node; }; - _.closeOpposing = function(brack) { + closeOpposing (brack) { brack.side = 0; brack.sides[this.side] = this.sides[this.side]; // copy over my info (may be var $brack = brack.delimjQs.eq(this.side === L ? 0 : 1) // mismatched, like [a, b)) .removeClass('mq-ghost'); this.replaceBracket($brack, this.side); }; - _.createLeftOf = function(cursor) { + createLeftOf (cursor) { if (!this.replacedFragment) { // unless wrapping seln in brackets, // check if next to or inside an opposing one-sided bracket var opts = cursor.options; @@ -949,18 +961,18 @@ var Bracket = P(P(MathCommand, DelimsMixin), function(_, super_) { brack.replaces(new Fragment(cursor[-side], cursor.parent.ends[-side], side)); cursor[-side] = 0; } - super_.createLeftOf.call(brack, cursor); + super.createLeftOf(cursor); } if (side === L) cursor.insAtLeftEnd(brack.ends[L]); else cursor.insRightOf(brack); }; - _.placeCursor = noop; - _.unwrap = function() { + placeCursor () {}; + unwrap () { this.ends[L].children().disown().adopt(this.parent, this, this[R]) .jQ.insertAfter(this.jQ); this.remove(); }; - _.deleteSide = function(side, outward, cursor) { + deleteSide (side, outward, cursor) { var parent = this.parent, sib = this[side], farEnd = parent.ends[side]; if (side === this.side) { // deleting non-ghost of one-sided bracket, unwrap @@ -1008,7 +1020,7 @@ var Bracket = P(P(MathCommand, DelimsMixin), function(_, super_) { : cursor.insAtDirEnd(side, this.ends[L])); } }; - _.replaceBracket = function ($brack, side) { + replaceBracket ($brack, side) { var symbol = this.getSymbol(side); $brack.html(symbol.html).css('width', symbol.width); @@ -1018,10 +1030,10 @@ var Bracket = P(P(MathCommand, DelimsMixin), function(_, super_) { $brack.prev().css('margin-right', symbol.width); } }; - _.deleteTowards = function(dir, cursor) { + deleteTowards (dir, cursor) { this.deleteSide(-dir, false, cursor); }; - _.finalizeTree = function() { + finalizeTree () { this.ends[L].deleteOutOf = function(dir, cursor) { this.parent.deleteSide(dir, true, cursor); }; @@ -1032,10 +1044,10 @@ var Bracket = P(P(MathCommand, DelimsMixin), function(_, super_) { this.side = 0; }; }; - _.siblingCreated = function(opts, dir) { // if something typed between ghost and far + siblingCreated (opts, dir) { // if something typed between ghost and far if (dir === -this.side) this.finalizeTree(); // end of its block, solidify }; -}); +}; var OPP_BRACKS = { '(': ')', @@ -1063,18 +1075,18 @@ var BRACKET_NAMES = { function bindCharBracketPair(open, ctrlSeq, name) { var ctrlSeq = ctrlSeq || open, close = OPP_BRACKS[open], end = OPP_BRACKS[ctrlSeq]; - CharCmds[open] = bind(Bracket, L, open, close, ctrlSeq, end); - CharCmds[close] = bind(Bracket, R, open, close, ctrlSeq, end); + CharCmds[open] = () => new Bracket(L, open, close, ctrlSeq, end); + CharCmds[close] = () => new Bracket(R, open, close, ctrlSeq, end); BRACKET_NAMES[open] = BRACKET_NAMES[close] = name; } bindCharBracketPair('(', null, 'parenthesis'); bindCharBracketPair('[', null, 'bracket'); bindCharBracketPair('{', '\\{', 'brace'); -LatexCmds.langle = bind(Bracket, L, '⟨', '⟩', '\\langle ', '\\rangle '); -LatexCmds.rangle = bind(Bracket, R, '⟨', '⟩', '\\langle ', '\\rangle '); -CharCmds['|'] = bind(Bracket, L, '|', '|', '|', '|'); -LatexCmds.lVert = bind(Bracket, L, '∥', '∥', '\\lVert ', '\\rVert '); -LatexCmds.rVert = bind(Bracket, R, '∥', '∥', '\\lVert ', '\\rVert '); +LatexCmds.langle = () => new Bracket(L, '⟨', '⟩', '\\langle ', '\\rangle '); +LatexCmds.rangle = () => new Bracket(R, '⟨', '⟩', '\\langle ', '\\rangle '); +CharCmds['|'] = () => new Bracket(L, '|', '|', '|', '|'); +LatexCmds.lVert = () => new Bracket(L, '∥', '∥', '\\lVert ', '\\rVert '); +LatexCmds.rVert = () => new Bracket( '∥', '∥', '\\lVert ', '\\rVert '); LatexCmds.left = class extends MathCommand { @@ -1095,7 +1107,7 @@ LatexCmds.left = class extends MathCommand { var close = end.replace(/^\\/, ''); if (end=="\\rangle") { close = '⟩'; end = end + ' '; } if (end=="\\rVert") { close = '∥'; end = end + ' '; } - var cmd = Bracket(0, open, close, ctrlSeq, end); + var cmd = new Bracket(0, open, close, ctrlSeq, end); cmd.blocks = [ block ]; block.adopt(cmd, 0, 0); return cmd; From fcdd973a079bfb78c01c7784b75f56464ccc1f51 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 16:01:53 -0500 Subject: [PATCH 063/192] convert Binomial to ES6 class --- src/commands/math/commands.js | 46 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index 59df74d99..b4f8614a2 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -850,14 +850,6 @@ class DelimsNode extends MathCommand { }; } -function DelimsMixin(_, super_) { - _.jQadd = function() { - super_.jQadd.apply(this, arguments); - this.delimjQs = this.jQ.children(':first').add(this.jQ.children(':last')); - this.contentjQ = this.jQ.children(':eq(1)'); - }; -} - // Round/Square/Curly/Angle Brackets (aka Parens/Brackets/Braces) // first typed as one-sided bracket with matching "ghost" bracket at // far end of current block, until you type an opposing one @@ -1125,33 +1117,39 @@ LatexCmds.right = class extends MathCommand { }; }; -var Binomial = -LatexCmds.binom = -LatexCmds.binomial = P(P(MathCommand, DelimsMixin), function(_, super_) { - var leftSymbol = SVG_SYMBOLS['(']; - var rightSymbol = SVG_SYMBOLS[')']; +var leftBinomialSymbol = SVG_SYMBOLS['(']; +var rightBinomialSymbol = SVG_SYMBOLS[')']; +class Binomial extends DelimsNode { - _.ctrlSeq = '\\binom'; - _.htmlTemplate = + static _todoMoveIntoConstructor = + Binomial.prototype.ctrlSeq = '\\binom'; + static _todoMoveIntoConstructor = + Binomial.prototype.htmlTemplate = '' - + '' - + leftSymbol.html + + '' + + leftBinomialSymbol.html + '' - + '' + + '' + '' + '&0' + '&1' + '' + '' - + '' - + rightSymbol.html + + '' + + rightBinomialSymbol.html + '' + '' ; - _.textTemplate = ['choose(',',',')']; - _.mathspeakTemplate = ['StartBinomial,', 'Choose', ', EndBinomial']; - _.ariaLabel = 'binomial'; -}); + static _todoMoveIntoConstructor = + Binomial.prototype.textTemplate = ['choose(',',',')']; + static _todoMoveIntoConstructor = + Binomial.prototype.mathspeakTemplate = ['StartBinomial,', 'Choose', ', EndBinomial']; + static _todoMoveIntoConstructor = + Binomial.prototype.ariaLabel = 'binomial'; +}; + +LatexCmds.binom = +LatexCmds.binomial = Binomial; var Choose = LatexCmds.choose = P(Binomial, function(_) { From e3ded45abaf14b447bcb2921c8a3d91a9b213f3d Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 16:03:24 -0500 Subject: [PATCH 064/192] convert LatexCmds.choose to ES6 class --- src/commands/math/commands.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index b4f8614a2..a691f2154 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -1151,10 +1151,11 @@ class Binomial extends DelimsNode { LatexCmds.binom = LatexCmds.binomial = Binomial; -var Choose = -LatexCmds.choose = P(Binomial, function(_) { - _.createLeftOf = LiveFraction.prototype.createLeftOf; -}); +LatexCmds.choose = class extends Binomial { + createLeftOf (cursor) { + LiveFraction.prototype.createLeftOf.call(this, cursor); + } +}; LatexCmds.editable = // backcompat with before cfd3620 on #233 LatexCmds.MathQuillMathField = class MathFieldNode extends MathCommand { From 382dd5fa94878bb0353c56d30ff39a9d7e175fdd Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 16:09:09 -0500 Subject: [PATCH 065/192] convert ChNode to ES6 class --- test/unit/tree.test.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/test/unit/tree.test.js b/test/unit/tree.test.js index 934825f81..e814506e4 100644 --- a/test/unit/tree.test.js +++ b/test/unit/tree.test.js @@ -175,18 +175,19 @@ suite('tree', function() { }); test('directionalized constructor call', function() { - var ChNode = P(Node, function (_, super_) { - _.init = function(ch) { - super_.init.call(this); - this.ch = ch; - } - }); + var ChNode = class extends Node { + constructor (ch) { + this.init(ch); + } + init (ch) { super.init(); this.ch = ch }; + } + var parent = new Node(); - var a = ChNode('a').adopt(parent, parent.ends[R], 0); - var b = ChNode('b').adopt(parent, parent.ends[R], 0); - var c = ChNode('c').adopt(parent, parent.ends[R], 0); - var d = ChNode('d').adopt(parent, parent.ends[R], 0); - var e = ChNode('e').adopt(parent, parent.ends[R], 0); + var a = new ChNode('a').adopt(parent, parent.ends[R], 0); + var b = new ChNode('b').adopt(parent, parent.ends[R], 0); + var c = new ChNode('c').adopt(parent, parent.ends[R], 0); + var d = new ChNode('d').adopt(parent, parent.ends[R], 0); + var e = new ChNode('e').adopt(parent, parent.ends[R], 0); function cat(str, node) { return str + node.ch; } assert.equal('bcd', new Fragment(b, d).fold('', cat)); From 089a8dbe73613015f357a435e1dc5316fb202315 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 16:13:01 -0500 Subject: [PATCH 066/192] convert LatexCommandInput to ES6 class --- src/commands/math/LatexCommandInput.js | 30 ++++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/commands/math/LatexCommandInput.js b/src/commands/math/LatexCommandInput.js index 6d527d7d7..06d1718bc 100644 --- a/src/commands/math/LatexCommandInput.js +++ b/src/commands/math/LatexCommandInput.js @@ -2,17 +2,19 @@ * Input box to type backslash commands ***************************************/ -var LatexCommandInput = -CharCmds['\\'] = P(MathCommand, function(_, super_) { - _.ctrlSeq = '\\'; - _.replaces = function(replacedFragment) { +CharCmds['\\'] = class LatexCommandInput extends MathCommand { + static _todoMoveIntoConstructor = + LatexCommandInput.prototype.ctrlSeq = '\\'; + replaces (replacedFragment) { this._replacedFragment = replacedFragment.disown(); this.isEmpty = function() { return false; }; }; - _.htmlTemplate = '\\&0'; - _.textTemplate = ['\\']; - _.createBlocks = function() { - super_.createBlocks.call(this); + static _todoMoveIntoConstructor = + LatexCommandInput.prototype.htmlTemplate = '\\&0'; + static _todoMoveIntoConstructor = + LatexCommandInput.prototype.textTemplate = ['\\']; + createBlocks () { + super.createBlocks(); this.ends[L].focus = function() { this.parent.jQ.addClass('mq-hasCursor'); if (this.isEmpty()) @@ -51,11 +53,11 @@ CharCmds['\\'] = P(MathCommand, function(_, super_) { e.preventDefault(); return; } - return super_.keystroke.apply(this, arguments); + return super.keystroke.apply(this, arguments); }; }; - _.createLeftOf = function(cursor) { - super_.createLeftOf.call(this, cursor); + createLeftOf (cursor) { + super.createLeftOf(cursor); if (this._replacedFragment) { var el = this.jQ[0]; @@ -69,10 +71,10 @@ CharCmds['\\'] = P(MathCommand, function(_, super_) { ).insertBefore(this.jQ).add(this.jQ); } }; - _.latex = function() { + latex () { return '\\' + this.ends[L].latex() + ' '; }; - _.renderCommand = function(cursor) { + renderCommand (cursor) { this.jQ = this.jQ.last(); this.remove(); if (this[R]) { @@ -103,5 +105,5 @@ CharCmds['\\'] = P(MathCommand, function(_, super_) { } return cmd; }; -}); +}; From a46637da13b947a6df0de3b0ee8e24be19366fbe Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 16:18:12 -0500 Subject: [PATCH 067/192] convert Aria to ES6 class --- Makefile | 2 +- src/controller.js | 6 ++++++ src/services/aria.js | 25 +++++++++---------------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 4ad1ebd57..f51610d53 100644 --- a/Makefile +++ b/Makefile @@ -28,13 +28,13 @@ PJS_SRC = ./node_modules/pjs/src/p.js BASE_SOURCES = \ $(PJS_SRC) \ + $(SRC_DIR)/services/aria.js \ $(SRC_DIR)/tree.js \ $(SRC_DIR)/cursor.js \ $(SRC_DIR)/controller.js \ $(SRC_DIR)/publicapi.js \ $(SRC_DIR)/services/parser.util.js \ $(SRC_DIR)/services/saneKeyboardEvents.util.js \ - $(SRC_DIR)/services/aria.js \ $(SRC_DIR)/services/exportText.js \ $(SRC_DIR)/services/focusBlur.js \ $(SRC_DIR)/services/keystroke.js \ diff --git a/src/controller.js b/src/controller.js index 13ee58672..f82c60d6b 100644 --- a/src/controller.js +++ b/src/controller.js @@ -103,4 +103,10 @@ var Controller = P(function(_) { this.container[0].contains(document.activeElement) ); }; + + _.aria = aria; + // based on http://www.gh-mathspeak.com/examples/quick-tutorial/ + // and http://www.gh-mathspeak.com/examples/grammar-rules/ + _.exportMathSpeak = function() { return this.root.mathspeak(); }; + }); diff --git a/src/services/aria.js b/src/services/aria.js index ea7f43096..9392af9a7 100755 --- a/src/services/aria.js +++ b/src/services/aria.js @@ -11,8 +11,8 @@ * Chrome 54+ on Android works reliably with Talkback. ****************************************/ -var Aria = P(function(_) { - _.init = function() { +class Aria { + constructor () { this.jQ = jQuery([]); // empty element // Add the alert DOM element only after the page has loaded. jQuery(document).ready(function() { @@ -25,7 +25,7 @@ var Aria = P(function(_) { this.msg = ''; }; - _.queue = function(item, shouldDescribe) { + queue (item, shouldDescribe) { var output = ''; if (item instanceof Node) { // Some constructs include verbal shorthand (such as simple fractions and exponents). @@ -52,16 +52,16 @@ var Aria = P(function(_) { this.items.push(output); return this; }; - _.queueDirOf = function(dir) { + queueDirOf (dir) { prayDirection(dir); return this.queue(dir === L ? 'before' : 'after'); }; - _.queueDirEndOf = function(dir) { + queueDirEndOf (dir) { prayDirection(dir); return this.queue(dir === L ? 'beginning of' : 'end of'); }; - _.alert = function(t) { + alert (t) { if (t) this.queue(t); if (this.items.length) { this.msg = this.items.join(' ').replace(/ +(?= )/g,'').trim(); @@ -70,18 +70,11 @@ var Aria = P(function(_) { return this.clear(); }; - _.clear = function() { + clear () { this.items.length = 0; return this; }; -}); +}; // We only ever need one instance of the ARIA alert object, and it needs to be easily accessible from all modules. -var aria = Aria(); - -Controller.open(function(_) { - _.aria = aria; - // based on http://www.gh-mathspeak.com/examples/quick-tutorial/ - // and http://www.gh-mathspeak.com/examples/grammar-rules/ - _.exportMathSpeak = function() { return this.root.mathspeak(); }; -}); +var aria = new Aria(); From c9425a6ec588e0c1c1abedb7b60d377a03d081d4 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 16:39:17 -0500 Subject: [PATCH 068/192] convert Parser to ES6 class --- src/services/parser.util.js | 96 +++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/src/services/parser.util.js b/src/services/parser.util.js index db76ed5ae..a49a28c48 100644 --- a/src/services/parser.util.js +++ b/src/services/parser.util.js @@ -1,37 +1,39 @@ -var Parser = P(function(_, super_, Parser) { + +function parseError(stream, message) { + if (stream) { + stream = "'"+stream+"'"; + } + else { + stream = 'EOF'; + } + + throw 'Parse Error: '+message+' at '+stream; +} + +class Parser { // The Parser object is a wrapper for a parser function. // Externally, you use one to parse a string by calling // var result = SomeParser.parse('Me Me Me! Parse Me!'); // You should never call the constructor, rather you should // construct your Parser from the base parsers and the // parser combinator methods. - - function parseError(stream, message) { - if (stream) { - stream = "'"+stream+"'"; - } - else { - stream = 'EOF'; - } - - throw 'Parse Error: '+message+' at '+stream; + constructor (body) { + this._ = body; } - _.init = function(body) { this._ = body; }; - - _.parse = function(stream) { - return this.skip(eof)._(''+stream, success, parseError); + parse (stream) { + return this.skip(Parser.eof)._(''+stream, success, parseError); function success(stream, result) { return result; } }; // -*- primitive combinators -*- // - _.or = function(alternative) { + or (alternative) { pray('or is passed a parser', alternative instanceof Parser); var self = this; - return Parser(function(stream, onSuccess, onFailure) { + return new Parser(function(stream, onSuccess, onFailure) { return self._(stream, onSuccess, failure); function failure(newStream) { @@ -40,10 +42,10 @@ var Parser = P(function(_, super_, Parser) { }); }; - _.then = function(next) { + then (next) { var self = this; - return Parser(function(stream, onSuccess, onFailure) { + return new Parser(function(stream, onSuccess, onFailure) { return self._(stream, success, onFailure); function success(newStream, result) { @@ -55,10 +57,10 @@ var Parser = P(function(_, super_, Parser) { }; // -*- optimized iterative combinators -*- // - _.many = function() { + many () { var self = this; - return Parser(function(stream, onSuccess, onFailure) { + return new Parser(function(stream, onSuccess, onFailure) { var xs = []; while (self._(stream, success, failure)); return onSuccess(stream, xs); @@ -75,11 +77,11 @@ var Parser = P(function(_, super_, Parser) { }); }; - _.times = function(min, max) { + times (min, max) { if (arguments.length < 2) max = min; var self = this; - return Parser(function(stream, onSuccess, onFailure) { + return new Parser(function(stream, onSuccess, onFailure) { var xs = []; var result = true; var failure; @@ -114,9 +116,9 @@ var Parser = P(function(_, super_, Parser) { }; // -*- higher-level combinators -*- // - _.result = function(res) { return this.then(succeed(res)); }; - _.atMost = function(n) { return this.times(0, n); }; - _.atLeast = function(n) { + result (res) { return this.then(Parser.succeed(res)); }; + atMost (n) { return this.times(0, n); }; + atLeast (n) { var self = this; return self.times(n).then(function(start) { return self.many().map(function(end) { @@ -125,20 +127,20 @@ var Parser = P(function(_, super_, Parser) { }); }; - _.map = function(fn) { - return this.then(function(result) { return succeed(fn(result)); }); + map (fn) { + return this.then(function(result) { return Parser.succeed(fn(result)); }); }; - _.skip = function(two) { + skip (two) { return this.then(function(result) { return two.result(result); }); }; // -*- primitive parsers -*- // - var string = this.string = function(str) { + static string (str) { var len = str.length; var expected = "expected '"+str+"'"; - return Parser(function(stream, onSuccess, onFailure) { + return new Parser(function(stream, onSuccess, onFailure) { var head = stream.slice(0, len); if (head === str) { @@ -150,12 +152,12 @@ var Parser = P(function(_, super_, Parser) { }); }; - var regex = this.regex = function(re) { + static regex (re) { pray('regexp parser is anchored', re.toString().charAt(1) === '^'); var expected = 'expected '+re; - return Parser(function(stream, onSuccess, onFailure) { + return new Parser(function(stream, onSuccess, onFailure) { var match = re.exec(stream); if (match) { @@ -168,38 +170,38 @@ var Parser = P(function(_, super_, Parser) { }); }; - var succeed = Parser.succeed = function(result) { - return Parser(function(stream, onSuccess) { + static succeed (result) { + return new Parser(function(stream, onSuccess) { return onSuccess(stream, result); }); }; - var fail = Parser.fail = function(msg) { - return Parser(function(stream, _, onFailure) { + static fail (msg) { + return new Parser(function(stream, _, onFailure) { return onFailure(stream, msg); }); }; - var letter = Parser.letter = regex(/^[a-z]/i); - var letters = Parser.letters = regex(/^[a-z]*/i); - var digit = Parser.digit = regex(/^[0-9]/); - var digits = Parser.digits = regex(/^[0-9]*/); - var whitespace = Parser.whitespace = regex(/^\s+/); - var optWhitespace = Parser.optWhitespace = regex(/^\s*/); + static letter = Parser.regex(/^[a-z]/i); + static letters = Parser.regex(/^[a-z]*/i); + static digit = Parser.regex(/^[0-9]/); + static digits = Parser.regex(/^[0-9]*/); + static whitespace = Parser.regex(/^\s+/); + static optWhitespace = Parser.regex(/^\s*/); - var any = Parser.any = Parser(function(stream, onSuccess, onFailure) { + static any = new Parser(function(stream, onSuccess, onFailure) { if (!stream) return onFailure(stream, 'expected any character'); return onSuccess(stream.slice(1), stream.charAt(0)); }); - var all = Parser.all = Parser(function(stream, onSuccess, onFailure) { + static all = new Parser(function(stream, onSuccess, onFailure) { return onSuccess('', stream); }); - var eof = Parser.eof = Parser(function(stream, onSuccess, onFailure) { + static eof = new Parser(function(stream, onSuccess, onFailure) { if (stream) return onFailure(stream, 'expected EOF'); return onSuccess(stream, stream); }); -}); +}; From d5c2516917d6b14ba37fd55114f056feca791997 Mon Sep 17 00:00:00 2001 From: Mike Haverstock Date: Wed, 1 Dec 2021 18:12:58 -0500 Subject: [PATCH 069/192] convert Options to ES6 class --- src/commands/math.js | 2 +- src/commands/math/basicSymbols.js | 6 +++--- src/commands/math/commands.js | 2 +- src/publicapi.js | 7 ++++--- src/services/mouse.js | 2 +- src/services/textarea.js | 4 ++-- test/unit/latex.test.js | 2 +- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/commands/math.js b/src/commands/math.js index 90d49a31b..933b12662 100644 --- a/src/commands/math.js +++ b/src/commands/math.js @@ -594,7 +594,7 @@ class MathBlock extends MathElement { }; } -Options.p.mouseEvents = true; +Options.prototype.mouseEvents = true; API.StaticMath = function(APIClasses) { return P(APIClasses.AbstractMathQuill, function(_, super_) { this.RootBlock = MathBlock; diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js index 89192c205..12015d2ed 100644 --- a/src/commands/math/basicSymbols.js +++ b/src/commands/math/basicSymbols.js @@ -244,7 +244,7 @@ function bindVariable (ch, html) { } -Options.p.autoCommands = { _maxLength: 0 }; +Options.prototype.autoCommands = { _maxLength: 0 }; optionProcessors.autoCommands = function(cmds) { if (!/^[a-z]+(?: [a-z]+)*$/i.test(cmds)) { throw '"'+cmds+'" not a space-delimited list of only letters'; @@ -265,7 +265,7 @@ optionProcessors.autoCommands = function(cmds) { return dict; }; -Options.p.autoParenthesizedFunctions = {_maxLength: 0}; +Options.prototype.autoParenthesizedFunctions = {_maxLength: 0}; optionProcessors.autoParenthesizedFunctions = function (cmds) { if (!/^[a-z]+(?: [a-z]+)*$/i.test(cmds)) { throw '"'+cmds+'" not a space-delimited list of only letters'; @@ -458,7 +458,7 @@ var BuiltInOpNames = {}; // the set of operator names like \sin, \cos, etc that // and 'arsinh', which must be exported as \operatorname{hcf} and // \operatorname{arsinh}. Note: over/under line/arrow \lim variants like // \varlimsup are not supported -var AutoOpNames = Options.p.autoOperatorNames = { _maxLength: 9 }; // the set +var AutoOpNames = Options.prototype.autoOperatorNames = { _maxLength: 9 }; // the set // of operator names that MathQuill auto-unitalicizes by default; overridable var TwoWordOpNames = { limsup: 1, liminf: 1, projlim: 1, injlim: 1 }; (function() { diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js index a691f2154..b479f5c0e 100644 --- a/src/commands/math/commands.js +++ b/src/commands/math/commands.js @@ -223,7 +223,7 @@ function getCtrlSeqsFromBlock(block) { return chars; } -Options.p.charsThatBreakOutOfSupSub = ''; +Options.prototype.charsThatBreakOutOfSupSub = ''; class SupSub extends MathCommand { static _todoMoveIntoConstructor = diff --git a/src/publicapi.js b/src/publicapi.js index 1157ce420..8d0ba7c28 100644 --- a/src/publicapi.js +++ b/src/publicapi.js @@ -2,7 +2,8 @@ * The publicly exposed MathQuill API. ********************************************************/ -var API = {}, Options = P(), optionProcessors = {}, Progenote = P(), EMBEDS = {}; +var API = {}, optionProcessors = {}, Progenote = P(), EMBEDS = {}; +class Options {}; /** * Interface Versioning (#459, #495) to allow us to virtually guarantee @@ -89,7 +90,7 @@ function getInterface(v) { currentOptions[name] = (processor ? processor(value) : value); } } - MQ.config = function(opts) { config(Options.p, opts); return this; }; + MQ.config = function(opts) { config(Options.prototype, opts); return this; }; MQ.registerEmbed = function(name, options) { if (!/^[a-z][a-z0-9]*$/i.test(name)) { throw 'Embed name must start with letter and be only letters and digits'; @@ -274,7 +275,7 @@ function getInterface(v) { MQ[kind] = function(el, opts) { var mq = MQ(el); if (mq instanceof APIClass || !el || !el.nodeType) return mq; - var ctrlr = Controller(new APIClass.RootBlock(), $(el), Options()); + var ctrlr = Controller(new APIClass.RootBlock(), $(el), new Options()); ctrlr.KIND_OF_MQ = kind; return APIClass(ctrlr).__mathquillify(opts, v); }; diff --git a/src/services/mouse.js b/src/services/mouse.js index b6d4b8b96..b57c9f0b7 100644 --- a/src/services/mouse.js +++ b/src/services/mouse.js @@ -3,7 +3,7 @@ *******************************************************/ Controller.open(function(_) { - Options.p.ignoreNextMousedown = noop; + Options.prototype.ignoreNextMousedown = noop; // Whenever edits to the tree occur, in-progress selection events // must be invalidated and selection changes must not be applied to diff --git a/src/services/textarea.js b/src/services/textarea.js index 78f04d102..fcfb30401 100644 --- a/src/services/textarea.js +++ b/src/services/textarea.js @@ -4,7 +4,7 @@ ********************************************/ Controller.open(function(_) { - Options.p.substituteTextarea = function() { + Options.prototype.substituteTextarea = function() { return $('