Merge pull request #603 from mathquill/feature.integrals

Feature: integrals' from/to now mandatory, prettier
diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js
index 414edaa..f4e1381 100644
--- a/src/commands/math/commands.js
+++ b/src/commands/math/commands.js
@@ -181,7 +181,6 @@
         break;
       }
     }
-    this.respace();
   };
   Options.p.charsThatBreakOutOfSupSub = '';
   _.finalizeTree = function() {
@@ -230,10 +229,6 @@
     }
     return latex('_', this.sub) + latex('^', this.sup);
   };
-  _.respace = _.siblingCreated = _.siblingDeleted = function(opts, dir) {
-    if (dir === R) return; // ignore if sibling only changed on the right
-    this.jQ.toggleClass('mq-limit', this[L].ctrlSeq === '\\int ');
-  };
   _.addBlock = function(block) {
     if (this.supsub === 'sub') {
       this.sup = this.upInto = this.sub.upOutOf = block;
@@ -382,7 +377,23 @@
 
 LatexCmds['∫'] =
 LatexCmds['int'] =
-LatexCmds.integral = bind(Symbol,'\\int ','<big>&int;</big>');
+LatexCmds.integral = P(SummationNotation, function(_, super_) {
+  _.init = function() {
+    var htmlTemplate =
+      '<span class="mq-int mq-non-leaf">'
+    +   '<big>&int;</big>'
+    +   '<span class="mq-supsub mq-non-leaf">'
+    +     '<span class="mq-sup"><span class="mq-sup-inner">&1</span></span>'
+    +     '<span class="mq-sub">&0</span>'
+    +     '<span style="display:inline-block;width:0">&#8203</span>'
+    +   '</span>'
+    + '</span>'
+    ;
+    Symbol.prototype.init.call(this, '\\int ', htmlTemplate);
+  };
+  // FIXME: refactor rather than overriding
+  _.createLeftOf = MathCommand.p.createLeftOf;
+});
 
 var Fraction =
 LatexCmds.frac =
diff --git a/src/css/math.less b/src/css/math.less
index 49a4214..9b7fb9e 100644
--- a/src/css/math.less
+++ b/src/css/math.less
@@ -90,6 +90,28 @@
     font-size: 200%;
   }
 
+  .mq-int {
+    > big {
+      display: inline-block;
+      .transform(scaleX(.7));
+      vertical-align: -.16em;
+    }
+
+    > .mq-supsub {
+      font-size: 80%;
+      vertical-align: -1.1em;
+      padding-right: .2em;
+
+      > .mq-sup > .mq-sup-inner {
+        vertical-align: 1.3em;
+      }
+
+      > .mq-sub {
+        margin-left: -.35em;
+      }
+    }
+  }
+
   .mq-roman {
     font-style: normal;
   }
@@ -132,10 +154,6 @@
     text-align: left;
     font-size: 90%;
     vertical-align: -.5em;
-    &.mq-limit {
-      font-size: 80%;
-      vertical-align: -.4em;
-    }
 
     &.mq-sup-only {
       vertical-align: .5em;
@@ -154,9 +172,6 @@
       display: block;
       float: left;
     }
-    &.mq-limit .mq-sub {
-      margin-left: -.25em;
-    }
 
     .mq-binary-operator {
       padding: 0 .1em;
diff --git a/test/unit/publicapi.test.js b/test/unit/publicapi.test.js
index a2c62c3..5453e7f 100644
--- a/test/unit/publicapi.test.js
+++ b/test/unit/publicapi.test.js
@@ -744,6 +744,20 @@
 
       $(mq.el()).remove();
     });
+    test('integral still has empty limits', function() {
+      var mq = MQ.MathField($('<span>').appendTo('#mock')[0], {
+        sumStartsWithNEquals: true
+      });
+      assert.equal(mq.latex(), '');
+
+      mq.cmd('\\int');
+      assert.equal(mq.latex(), '\\int_{ }^{ }');
+
+      mq.cmd('0');
+      assert.equal(mq.latex(), '\\int_0^{ }', 'cursor in the from block');
+
+      $(mq.el()).remove();
+    });
   });
 
   suite('substituteTextarea', function() {
diff --git a/test/visual.html b/test/visual.html
index cda3f14..1d2cf15 100644
--- a/test/visual.html
+++ b/test/visual.html
@@ -24,6 +24,9 @@
 td {

   width: 33%;

 }

+#static-latex-rendering-table td {

+  width: 50%;

+}

 #show-textareas-button {

   float: right;

 }

@@ -81,10 +84,10 @@
 

 <h3>Redrawing</h3>

 <p>

-  <span id="reflowing-test">\sqrt{_0^1}</span>

+  <span id="reflowing-test">\sqrt{}</span>

   should look the same as

   <span class="mathquill-static-math">

-    \sqrt{\pi\sqrt\sqrt\frac12\int_0^1}

+    \sqrt{\pi\sqrt\sqrt\frac12}

   </span>

 </p>

 <script type="text/javascript">

@@ -96,7 +99,7 @@
     var textarea = $('#reflowing-test textarea');

     // paste some stuff that needs resizing

     textarea.trigger('paste');

-    textarea.val('\\pi\\sqrt{\\sqrt{\\frac12}}\\int');

+    textarea.val('\\pi\\sqrt{\\sqrt{\\frac12}}');

     setTimeout(function() { if (count !== 1) throw 'reflow not called'; });

   });

 </script>

@@ -183,7 +186,7 @@
 </table>

 

 <h3>Static LaTeX rendering (<code>.mathquill-static-math</code>) tests</h3>

-<table>

+<table id="static-latex-rendering-table">

 <tr><td><span class="mathquill-static-math">^{\frac{as}{ }df}</span><td><span>^{\frac{as}{ }df}</span>

 <tr><td><span class="mathquill-static-math">e^{i\pi}+1=0</span><td><span>e^{i\pi}+1=0</span>

 <tr><td><span class="mathquill-static-math">\sqrt[n]{1}</span><td><span>\sqrt[n]{1}</span>

@@ -207,6 +210,8 @@
 <tr><td><span class="mathquill-static-math">1+\sum_0^n+\sum_{i=0123}^n+\sum_0^{wordiness}</span><td><span>1+\sum_0^n+\sum_{i=0123}^n+\sum_0^{wordiness}</span>^M

 <tr><td><span class="mathquill-static-math">x\ \ \ +\ \ \ y</span><td><span>x\ \ \ +\ \ \ y</span>^M

 <tr><td><span class="mathquill-static-math">\sum _{n=0}^3\cos x</span><td><span>\sum _{n=0}^3\cos x</span>^M

+<tr><td><span class="mathquill-static-math">\int _{\phi =0}^{2\pi }\int _{\theta =0}^{\pi }\int _{r=0}^{\infty }f(r,\theta ,\phi )r^2\sin \theta drd\theta d\phi </span><td><span>\int _{\phi =0}^{2\pi }\int _{\theta =0}^{\pi }\int _{r=0}^{\infty }f(r,\theta ,\phi )r^2\sin \theta drd\theta d\phi </span>

+<tr><td><span class="mathquill-static-math">\int_0^{\frac{\frac{1}{2}}{3}} \int_0^{\frac{1}{\frac{2}{3}}} \int_0^{\frac{1}{\frac{2}{\frac{3}{\frac{4}{5}}}}}</span><td><span>\int_0^{\frac{\frac{1}{2}}{3}} \int_0^{\frac{1}{\frac{2}{3}}} \int_0^{\frac{1}{\frac{2}{\frac{3}{\frac{4}{5}}}}}</span>

 <tr><td colspan=2><span id="sixes"></span>

 <script>

 $(function() {