scribble-math/domTree.js
Emily Eisenberg f52c84c187 Add limit operators
Summary:
Add support for all of the other operators, including the ones with symbols and
limits. This also fixes the bug where subscripts were shifted the same amount as
subscripts.

To accomplish this, the domTree.textNode has been repurposed into symbolNode
which is no longer an actual text node, but instead represents an element with a
single symbol in it. This lets us access properties like the italic correction
of a symbol in a reasonable manner without having to recursively look through
children of spans.

Depends on D13082

Fixes #8

Test Plan:
 - Make sure tests work
 - Make sure huxley screenshots didn't change much, and new screenshot looks good

Reviewers: alpert

Reviewed By: alpert

Differential Revision: http://phabricator.khanacademy.org/D13122
2014-09-12 14:58:58 -07:00

104 lines
2.7 KiB
JavaScript

// These objects store the data about the DOM nodes we create, as well as some
// extra data. They can then be transformed into real DOM nodes with the toDOM
// function. They are useful for both storing extra properties on the nodes, as
// well as providing a way to easily work with the DOM.
var createClass = function(classes) {
classes = classes.slice();
for (var i = classes.length - 1; i >= 0; i--) {
if (!classes[i]) {
classes.splice(i, 1);
}
}
return classes.join(" ");
};
function span(classes, children, height, depth, maxFontSize, style) {
this.classes = classes || [];
this.children = children || [];
this.height = height || 0;
this.depth = depth || 0;
this.maxFontSize = maxFontSize || 0;
this.style = style || {};
}
span.prototype.toDOM = function() {
var span = document.createElement("span");
span.className = createClass(this.classes);
for (var style in this.style) {
if (this.style.hasOwnProperty(style)) {
span.style[style] = this.style[style];
}
}
for (var i = 0; i < this.children.length; i++) {
span.appendChild(this.children[i].toDOM());
}
return span;
};
function documentFragment(children, height, depth, maxFontSize) {
this.children = children || [];
this.height = height || 0;
this.depth = depth || 0;
this.maxFontSize = maxFontSize || 0;
}
documentFragment.prototype.toDOM = function() {
var frag = document.createDocumentFragment();
for (var i = 0; i < this.children.length; i++) {
frag.appendChild(this.children[i].toDOM());
}
return frag;
};
function symbolNode(value, height, depth, italic, classes, style) {
this.value = value || "";
this.height = height || 0;
this.depth = depth || 0;
this.italic = italic || 0;
this.classes = classes || [];
this.style = style || {};
}
symbolNode.prototype.toDOM = function() {
var node = document.createTextNode(this.value);
var span = null;
if (this.italic > 0) {
span = document.createElement("span");
span.style.marginRight = this.italic + "em";
}
if (this.classes.length > 0) {
span = span || document.createElement("span");
span.className = createClass(this.classes);
}
for (var style in this.style) {
if (this.style.hasOwnProperty(style)) {
span = span || document.createElement("span");
span.style[style] = this.style[style];
}
}
if (span) {
span.appendChild(node);
return span;
} else {
return node;
}
};
module.exports = {
span: span,
documentFragment: documentFragment,
symbolNode: symbolNode
};