Merge pull request #598 from Learnosity/woff-fonts-update
[LRN] Added WOFF and WOFF2 fonts built from OTF
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3d2d549..4a787ed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,40 @@
+## v0.10.1: 2016-03-21
+
+Important fix: remove `font-size: 0` on textarea (#585), fixing typing
+in Chrome Canary (#540) as well as the Enter key not triggering the
+`enter` handler in Webkit and Blink (#566). `transform: scale(0)` is
+used instead and expected to be much more robust.
+
+(Note: if you're coming from v0.9.x, there've been major API changes,
+see the [v0.9.x → v0.10.0 Migration Guide][].)
+
+[v0.9.x → v0.10.0 Migration Guide]: https://github.com/mathquill/mathquill/wiki/v0.9.x-%E2%86%92-v0.10.0-Migration-Guide
+
+**new features:**
+- (#544, #552, #558, #581) new symbols `\nparallel`, `\measuredangle`,
+ `\odot`, `\parallelogram` (nonstandard), `\nless`, `\ngtr`, `\square`
+- (#544) new commands `\overleftarrow`, `\overrightarrow`
+
+
+**bugfixes:**
+- (#585) fix typing in Chrome Canary, Enter key in Webkit+Blink
+- (#582) fix `\degree` symbol to round-trip (rather than exporting
+ `^\circ` which doesn't parse as one symbol)
+- (#578) fix `.text()` to output `\cdot` as `*`
+- (#529, #571, #574) fix `.text()` of fractions, spaces, variables followed
+ by exponents
+- (#577) fix `\triangle` symbol to match LaTeX better
+- (#568) hotfix #435 order-dependence breaking clean build on Linux
+- (#560) fix florin spacing still too close
+- (#546) fix parsing or pasting `×` (Unicode times symbol)
+- (#519/#487) fix auto-horizontal-scroll/pan on API calls
+- (#528) fix #429 can't move cursor out of `TextBlock`
+- (#526) fix exponentiation to export `^` not `**`
+- (#525) fix Tab while there's a selection
+
+**build system fixes:**
+- (#532) add console output to show URL of local test pages
+
## v0.10.0: 2016-02-20
Many major changes including a total overhaul of the API (no more
diff --git a/Makefile b/Makefile
index 39df479..dcb2497 100644
--- a/Makefile
+++ b/Makefile
@@ -56,8 +56,9 @@
CLEAN += $(BUILD_DIR)/*
DISTDIR = ./mathquill-$(VERSION)
-DIST = $(DISTDIR).tgz
-CLEAN += $(DIST)
+DISTTAR = $(DISTDIR).tgz
+DISTZIP = $(DISTDIR).zip
+CLEAN += $(DISTTAR) $(DISTZIP)
# programs and flags
UGLIFY ?= ./node_modules/.bin/uglifyjs
@@ -92,7 +93,6 @@
uglify: $(UGLY_JS)
css: $(BUILD_CSS)
font: $(FONT_TARGET)
-dist: $(DIST)
clean:
rm -rf $(CLEAN)
@@ -117,7 +117,7 @@
$(LESSC) --modify-var="basic=true" $(LESS_OPTS) $(CSS_MAIN) > $@
$(NODE_MODULES_INSTALLED): package.json
- npm install
+ NODE_ENV=development npm install
touch $(NODE_MODULES_INSTALLED)
$(BUILD_DIR_EXISTS):
@@ -128,10 +128,11 @@
rm -rf $@
cp -r $< $@
-$(DIST): $(UGLY_JS) $(BUILD_JS) $(BUILD_CSS) $(FONT_TARGET)
+dist: $(UGLY_JS) $(BUILD_JS) $(BUILD_CSS) $(FONT_TARGET)
rm -rf $(DISTDIR)
cp -r $(BUILD_DIR) $(DISTDIR)
- tar -czf $(DIST) --exclude='\.gitkeep' $(DISTDIR)
+ zip -r -X $(DISTZIP) $(DISTDIR)
+ tar -czf $(DISTTAR) $(DISTDIR)
rm -r $(DISTDIR)
#
@@ -147,83 +148,3 @@
$(BUILD_TEST): $(INTRO) $(SOURCES_FULL) $(UNIT_TESTS) $(OUTRO) $(BUILD_DIR_EXISTS)
cat $^ > $@
-
-#
-# -*- site (mathquill.github.com) tasks
-#
-
-.PHONY: site publish site-pull
-
-SITE = mathquill.github.com
-SITE_CLONE_URL = git@github.com:mathquill/mathquill.github.com
-SITE_COMMITMSG = 'updating mathquill to $(VERSION)'
-
-DOWNLOADS_PAGE = $(SITE)/downloads.html
-DIST_DOWNLOAD = $(SITE)/downloads/$(DIST)
-
-site: $(SITE) $(SITE)/mathquill $(SITE)/demo.html $(SITE)/support $(DOWNLOADS_PAGE)
-
-publish: site-pull site
- pwd
- cd $(SITE) \
- && git add -- mathquill demo.html support downloads downloads.html \
- && git commit -m $(SITE_COMMITMSG) \
- && git push
-
-$(SITE)/mathquill: $(DIST)
- mkdir -p $@
- tar -xzf $(DIST) \
- --directory $@ \
- --strip-components=2
-
-$(DIST_DOWNLOAD): $(DIST)
- mkdir -p $(dir $@)
- cp $^ $@
-
-# freaking bsd, i swear
-# adapted from https://developer.apple.com/library/mac/documentation/opensource/Conceptual/ShellScripting/PortingScriptstoMacOSX/PortingScriptstoMacOSX.html#//apple_ref/doc/uid/TP40004268-TP40003517-SW21
-ifeq (x, $(shell echo xy | sed -r 's/(x)y/\1/' 2>/dev/null))
- # gnu
- SED = sed -r
- SED_I = $(SED) -i
-else
- # bsd
- SED = sed -E
- SED_I = $(SED) -i ''
-endif
-
-$(DOWNLOADS_PAGE): $(DIST_DOWNLOAD)
- @echo Using $(SED)
- @echo -n updating downloads page...
- @$(SED_I) \
- -e '/Latest version:/ s/[0-9]+[.][0-9]+[.][0-9]+/$(VERSION)/g' \
- $(DOWNLOADS_PAGE)
- @mkdir -p tmp
- @ls $(SITE)/downloads/*.tgz \
- | egrep -o '[0-9]+[.][0-9]+[.][0-9]+' \
- | fgrep -v $(VERSION) \
- | sort -rn -t. -k 1,1 -k 2,2 -k 3,3 \
- | sed 's|.*|<li><a class="prev" href="downloads/mathquill-&.tgz">v&</a></li>|' \
- > tmp/versions-list.html
- @$(SED_I) \
- -e '/<a class="prev"/d' \
- -e '/<ul id="prev-versions">/ r tmp/versions-list.html' \
- $(DOWNLOADS_PAGE)
- @rm tmp/versions-list.html
- @echo done.
-
-$(SITE)/demo.html: test/demo.html
- cat $^ \
- | $(SED) 's:../build/:mathquill/:' \
- | $(SED) 's:local test page:live demo:' \
- > $@
-
-$(SITE)/support: test/support
- rm -rf $@
- cp -r $^ $@
-
-$(SITE):
- git clone $(SITE_CLONE_URL) $@
-
-site-pull: $(SITE)
- cd $(SITE) && git pull
diff --git a/README.md b/README.md
index 7b93213..956bee5 100644
--- a/README.md
+++ b/README.md
@@ -144,6 +144,7 @@
Additionally, descendants of `MQ.EditableField` (currently only `MQ.MathField`)
expose:
+* `.focus()`, `.blur()` focuses or defocuses the editable field
* `.write(' - 1')` will write some LaTeX at the current cursor position
* `.cmd('\\sqrt')` will enter a LaTeX command at the current cursor position or
with the current selection
diff --git a/package.json b/package.json
index 703e3ec..e9889de 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "mathquill",
"description": "Easily type math in your webapp",
- "version": "0.10.0",
+ "version": "0.10.1",
"license": "MPL-2.0",
"repository": {
"type": "git",
diff --git a/src/commands/math/advancedSymbols.js b/src/commands/math/advancedSymbols.js
index a4dccb4..f5aa5a5 100644
--- a/src/commands/math/advancedSymbols.js
+++ b/src/commands/math/advancedSymbols.js
@@ -197,6 +197,7 @@
LatexCmds.spadesuit = bind(VanillaSymbol, '\\spadesuit ', '♠');
//not real LaTex command see https://github.com/mathquill/mathquill/pull/552 for more details
LatexCmds.parallelogram = bind(VanillaSymbol, '\\parallelogram ', '▱');
+LatexCmds.square = bind(VanillaSymbol, '\\square ', '⬜');
//variable-sized
LatexCmds.oint = bind(VanillaSymbol, '\\oint ', '∮');
@@ -221,10 +222,6 @@
LatexCmds.rbrack = bind(VanillaSymbol, ']');
//various symbols
-LatexCmds['∫'] =
-LatexCmds['int'] =
-LatexCmds.integral = bind(Symbol,'\\int ','<big>∫</big>');
-
LatexCmds.slash = bind(VanillaSymbol, '/');
LatexCmds.vert = bind(VanillaSymbol,'|');
LatexCmds.perp = LatexCmds.perpendicular = bind(VanillaSymbol,'\\perp ','⊥');
@@ -302,6 +299,9 @@
LatexCmds.xist = //LOL
LatexCmds.xists = LatexCmds.exist = LatexCmds.exists =
bind(VanillaSymbol,'\\exists ','∃');
+
+LatexCmds.nexists = LatexCmds.nexist =
+ bind(VanillaSymbol, '\\nexists ', '∄');
LatexCmds.and = LatexCmds.land = LatexCmds.wedge =
bind(VanillaSymbol,'\\wedge ','∧');
@@ -319,7 +319,8 @@
LatexCmds.cap = LatexCmds.intersect = LatexCmds.intersection =
bind(BinaryOperator,'\\cap ','∩');
-LatexCmds.deg = LatexCmds.degree = bind(VanillaSymbol,'^\\circ ','°');
+// FIXME: the correct LaTeX would be ^\circ but we can't parse that
+LatexCmds.deg = LatexCmds.degree = bind(VanillaSymbol,'\\degree ','°');
LatexCmds.ang = LatexCmds.angle = bind(VanillaSymbol,'\\angle ','∠');
LatexCmds.measuredangle = bind(VanillaSymbol,'\\measuredangle ','∡');
diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js
index 37c00bf..414edaa 100644
--- a/src/commands/math/commands.js
+++ b/src/commands/math/commands.js
@@ -380,6 +380,10 @@
LatexCmds.coprod =
LatexCmds.coproduct = bind(SummationNotation,'\\coprod ','∐');
+LatexCmds['∫'] =
+LatexCmds['int'] =
+LatexCmds.integral = bind(Symbol,'\\int ','<big>∫</big>');
+
var Fraction =
LatexCmds.frac =
LatexCmds.dfrac =
diff --git a/src/commands/text.js b/src/commands/text.js
index 42f85d4..d4352bd 100644
--- a/src/commands/text.js
+++ b/src/commands/text.js
@@ -48,10 +48,8 @@
return optWhitespace
.then(string('{')).then(regex(/^[^}]*/)).skip(string('}'))
.map(function(text) {
- // TODO: is this the correct behavior when parsing
- // the latex \text{} ? This violates the requirement that
- // the text contents are always nonempty. Should we just
- // disown the parent node instead?
+ if (text.length === 0) return Fragment();
+
TextPiece(text).adopt(textBlock, 0, 0);
return textBlock;
})
@@ -64,7 +62,11 @@
});
};
_.text = function() { return '"' + this.textContents() + '"'; };
- _.latex = function() { return '\\text{' + this.textContents() + '}'; };
+ _.latex = function() {
+ var contents = this.textContents();
+ if (contents.length === 0) return '';
+ return '\\text{' + contents + '}';
+ };
_.html = function() {
return (
'<span class="mq-text-mode" mathquill-command-id='+this.id+'>'
@@ -107,7 +109,7 @@
else { // split apart
var leftBlock = TextBlock();
var leftPc = this.ends[L];
- leftPc.disown();
+ leftPc.disown().jQ.detach();
leftPc.adopt(leftBlock, 0, 0);
cursor.insLeftOf(this);
@@ -162,15 +164,22 @@
}
};
- _.blur = function() {
+ _.blur = function(cursor) {
MathBlock.prototype.blur.call(this);
- fuseChildren(this);
+ if (!cursor) return;
+ if (this.textContents() === '') {
+ this.remove();
+ if (cursor[L] === this) cursor[L] = this[L];
+ else if (cursor[R] === this) cursor[R] = this[R];
+ }
+ else fuseChildren(this);
};
function fuseChildren(self) {
self.jQ[0].normalize();
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
diff --git a/src/css/main.less b/src/css/main.less
index a56bece..25dd7b4 100644
--- a/src/css/main.less
+++ b/src/css/main.less
@@ -1,5 +1,5 @@
/*
- * MathQuill v0.10.0 http://mathquill.com
+ * MathQuill v0.10.1 http://mathquill.com
* by Han, Jeanine, and Mary maintainers@mathquill.com
*
* This Source Code Form is subject to the terms of the
diff --git a/src/css/math.less b/src/css/math.less
index 6115ee8..fcaa23d 100644
--- a/src/css/math.less
+++ b/src/css/math.less
@@ -49,7 +49,14 @@
.mq-text-mode {
- font-size: 87%;
+ display: inline-block;
+ }
+ .mq-text-mode.mq-hasCursor {
+ box-shadow: inset darkgray 0 .1em .2em;
+ padding: 0 .1em;
+ margin: 0 -.1em;
+
+ min-width: 1ex;
}
.mq-font {
diff --git a/src/css/mixins/css3.less b/src/css/mixins/css3.less
index 2aecf28..b53bf6b 100644
--- a/src/css/mixins/css3.less
+++ b/src/css/mixins/css3.less
@@ -5,6 +5,13 @@
-o-transform-origin: @arguments;
transform-origin: @arguments;
}
+.transform (...) {
+ -webkit-transform: @arguments;
+ -moz-transform: @arguments;
+ -ms-transform: @arguments;
+ -o-transform: @arguments;
+ transform: @arguments;
+}
.user-select (...) {
-webkit-user-select: @arguments;
diff --git a/src/css/textarea.less b/src/css/textarea.less
index 487e1f1..1484fa7 100644
--- a/src/css/textarea.less
+++ b/src/css/textarea.less
@@ -14,7 +14,7 @@
position: absolute; // the only way to hide the textarea *and* the
clip: rect(1em 1em 1em 1em); // blinking insertion point in IE
- font-size: 0; // the only way to hide the blinking blue cursor in iOS 8
+ .transform(scale(0)); // the only way to hide the blinking blue cursor in iOS 8 #584
resize: none; // hotfix: https://code.google.com/p/chromium/issues/detail?id=355199#c1
diff --git a/src/cursor.js b/src/cursor.js
index b08b2f6..622a023 100644
--- a/src/cursor.js
+++ b/src/cursor.js
@@ -56,7 +56,8 @@
this[-dir] = oppDir;
// by contract, .blur() is called after all has been said and done
// and the cursor has actually been moved
- if (oldParent !== parent && oldParent.blur) oldParent.blur();
+ // 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) {
prayDirection(dir);
diff --git a/src/intro.js b/src/intro.js
index e1d9379..654b8cd 100644
--- a/src/intro.js
+++ b/src/intro.js
@@ -1,5 +1,5 @@
/**
- * MathQuill v0.10.0 http://mathquill.com
+ * MathQuill v0.10.1 http://mathquill.com
* by Han, Jeanine, and Mary maintainers@mathquill.com
*
* This Source Code Form is subject to the terms of the
diff --git a/src/publicapi.js b/src/publicapi.js
index 45b05e5..022dfda 100644
--- a/src/publicapi.js
+++ b/src/publicapi.js
@@ -15,7 +15,7 @@
function insistOnInterVer() {
if (window.console) console.warn(
'You are using the MathQuill API without specifying an interface version, ' +
- 'which will fail in v1.0.0. You can fix this easily by doing this before ' +
+ 'which will fail in v1.0.0. Easiest fix is to do the following before ' +
'doing anything else:\n' +
'\n' +
' MathQuill = MathQuill.getInterface(1);\n' +
diff --git a/src/services/keystroke.js b/src/services/keystroke.js
index 6ec672a..f3ec668 100644
--- a/src/services/keystroke.js
+++ b/src/services/keystroke.js
@@ -129,9 +129,6 @@
while (cursor[L]) ctrlr.selectLeft();
break;
- case 'Enter':
- return ctrlr.handle('enter');
-
default:
return;
}
diff --git a/src/services/latex.js b/src/services/latex.js
index 025f1a8..75369e8 100644
--- a/src/services/latex.js
+++ b/src/services/latex.js
@@ -1,6 +1,6 @@
-// Parser MathCommand
+// Parser MathBlock
var latexMathParser = (function() {
- function commandToBlock(cmd) {
+ function commandToBlock(cmd) { // can also take in a Fragment
var block = MathBlock();
cmd.adopt(block, 0, 0);
return block;
diff --git a/src/services/textarea.js b/src/services/textarea.js
index d178cbf..dd2d2de 100644
--- a/src/services/textarea.js
+++ b/src/services/textarea.js
@@ -86,6 +86,7 @@
this.focusBlurEvents();
};
_.typedText = function(ch) {
+ if (ch === '\n') return this.handle('enter');
var cursor = this.notify().cursor;
cursor.parent.write(cursor, ch);
this.scrollHoriz();
diff --git a/test/unit/backspace.test.js b/test/unit/backspace.test.js
index 51a34ca..688d1ba 100644
--- a/test/unit/backspace.test.js
+++ b/test/unit/backspace.test.js
@@ -197,7 +197,7 @@
assert.equal(mq.latex(),'n=1');
});
- test('backspace into text block', function() {
+ test('backspace through text block', function() {
mq.latex('\\text{x}');
mq.keystroke('Backspace');
@@ -206,6 +206,18 @@
assert.equal(cursor.parent, textBlock, 'cursor is in text block');
assert.equal(cursor[R], 0, 'cursor is at the end of text block');
assert.equal(cursor[L].text, 'x', 'cursor is rightward of the x');
+ assert.equal(mq.latex(), '\\text{x}', 'the x has been deleted');
+
+ mq.keystroke('Backspace');
+ assert.equal(cursor.parent, textBlock, 'cursor is still in text block');
+ assert.equal(cursor[R], 0, 'cursor is at the right end of the text block');
+ assert.equal(cursor[L], 0, 'cursor is at the left end of the text block');
+ assert.equal(mq.latex(), '', 'the x has been deleted');
+
+ mq.keystroke('Backspace');
+ assert.equal(cursor[R], 0, 'cursor is at the right end of the root block');
+ assert.equal(cursor[L], 0, 'cursor is at the left end of the root block');
+ assert.equal(mq.latex(), '');
});
suite('empties', function() {
diff --git a/test/unit/latex.test.js b/test/unit/latex.test.js
index 5795b18..4cf59fa 100644
--- a/test/unit/latex.test.js
+++ b/test/unit/latex.test.js
@@ -100,11 +100,14 @@
assertParsesLatex('\\text { lol! } ', '\\text{ lol! }');
assertParsesLatex('\\text{apples} \\ne \\text{oranges}',
'\\text{apples}\\ne \\text{oranges}');
+ assertParsesLatex('\\text{}', '');
});
test('not real LaTex commands, but valid symbols', function() {
assertParsesLatex('\\parallelogram ');
assertParsesLatex('\\circledot ', '\\odot ');
+ assertParsesLatex('\\degree ');
+ assertParsesLatex('\\square ');
});
suite('public API', function() {
diff --git a/test/unit/text.test.js b/test/unit/text.test.js
index 6f2ecd3..982a5ac 100644
--- a/test/unit/text.test.js
+++ b/test/unit/text.test.js
@@ -65,4 +65,43 @@
assert.equal(block.latex(), '\\text{x}');
});
+
+ test('stepping out of an empty block deletes it', function() {
+ var mq = MathQuill.MathField($('<span></span>').appendTo('#mock')[0]);
+ var controller = mq.__controller;
+ var cursor = controller.cursor;
+
+ try {
+ mq.latex('\\text{x}');
+
+ mq.keystroke('Left');
+ assertSplit(cursor.jQ, 'x');
+
+ mq.keystroke('Backspace');
+ assertSplit(cursor.jQ);
+
+ mq.keystroke('Right');
+ assertSplit(cursor.jQ);
+ assert.equal(cursor[L], 0);
+ } finally {
+ $(mq.el()).remove();
+ }
+ });
+
+ test('typing $ in a textblock splits it', function() {
+ var mq = MathQuill.MathField($('<span></span>').appendTo('#mock')[0]);
+ var controller = mq.__controller;
+ var cursor = controller.cursor;
+
+ try {
+ mq.latex('\\text{asdf}');
+ mq.keystroke('Left Left Left');
+ assertSplit(cursor.jQ, 'as', 'df');
+
+ mq.typedText('$');
+ assert.equal(mq.latex(), '\\text{as}\\text{df}');
+ } finally {
+ $(mq.el()).remove();
+ }
+ });
});