Merge branch 'master' into refactor.simplify-oppBrack
diff --git a/circle.yml b/circle.yml
index 0a162f0..f93227b 100644
--- a/circle.yml
+++ b/circle.yml
@@ -35,9 +35,6 @@
   cache_directories:
     - ~/sauce-connect
   pre:
-    # imagemagick is installed to give us access to the
-    # `convert` tool to stitch together the screenshots.
-    - sudo apt-get update; sudo apt-get install imagemagick
     - "test $SAUCE_USERNAME && test $SAUCE_ACCESS_KEY
        # Sauce Labs credentials required. Sign up here: https://saucelabs.com/opensauce/"
     - ? |-
diff --git a/docs/Api_Methods.md b/docs/Api_Methods.md
index 8271945..b7db00c 100644
--- a/docs/Api_Methods.md
+++ b/docs/Api_Methods.md
@@ -45,7 +45,7 @@
 ```html
 <span id="fill-in-the-blank">\sqrt{ \MathQuillMathField{x}^2 + \MathQuillMathField{y}^2 }</span>
 <script>
-  var fillInTheBlank = MQ.StaticMath(document.getElementById('#fill-in-the-blank'));
+  var fillInTheBlank = MQ.StaticMath(document.getElementById('fill-in-the-blank'));
   fillInTheBlank.innerFields[0].latex() // => 'x'
   fillInTheBlank.innerFields[1].latex() // => 'y'
 </script>
diff --git a/src/commands/math/basicSymbols.js b/src/commands/math/basicSymbols.js
index a8578ae..8c80b32 100644
--- a/src/commands/math/basicSymbols.js
+++ b/src/commands/math/basicSymbols.js
@@ -421,12 +421,28 @@
   _.init = VanillaSymbol.prototype.init;
 
   _.contactWeld = _.siblingCreated = _.siblingDeleted = function(opts, dir) {
+    function determineOpClassType(node) {
+      if (node[L]) {
+        // If the left sibling is a binary operator or a separator (comma, semicolon, colon)
+        // or an open bracket (open parenthesis, open square bracket)
+        // consider the operator to be unary
+        if (node[L] instanceof BinaryOperator || /^[,;:\(\[]$/.test(node[L].ctrlSeq)) {
+          return '';
+        }
+      } else if (node.parent && node.parent.parent && node.parent.parent.isStyleBlock()) {
+        //if we are in a style block at the leftmost edge, determine unary/binary based on
+        //the style block
+        //this allows style blocks to be transparent for unary/binary purposes
+        return determineOpClassType(node.parent.parent);
+      } else {
+        return '';
+      }
+
+      return 'mq-binary-operator';
+    };
+    
     if (dir === R) return; // ignore if sibling only changed on the right
-    // If the left sibling is a binary operator or a separator (comma, semicolon, colon)
-    // or an open bracket (open parenthesis, open square bracket)
-    // consider the operator to be unary, otherwise binary
-    this.jQ[0].className =
-      (!this[L] || this[L] instanceof BinaryOperator || /^[,;:\(\[]$/.test(this[L].ctrlSeq) ? '' : 'mq-binary-operator');
+    this.jQ[0].className = determineOpClassType(this);
     return this;
   };
 });
diff --git a/src/commands/math/commands.js b/src/commands/math/commands.js
index c6871e8..de5c53b 100644
--- a/src/commands/math/commands.js
+++ b/src/commands/math/commands.js
@@ -114,6 +114,9 @@
       })
     ;
   };
+  _.isStyleBlock = function() {
+    return true;
+  };
 });
 
 // Very similar to the \textcolor command, but will add the given CSS class.
@@ -133,6 +136,9 @@
       })
     ;
   };
+  _.isStyleBlock = function() {
+    return true;
+  };
 });
 
 var SupSub = P(MathCommand, function(_, super_) {
@@ -817,7 +823,7 @@
     return this;
   };
   _.parser = function() {
-    var self = this;
+    var self = this,
       string = Parser.string, regex = Parser.regex, succeed = Parser.succeed;
     return string('{').then(regex(/^[a-z][a-z0-9]*/i)).skip(string('}'))
       .then(function(name) {
diff --git a/src/css/textarea.less b/src/css/textarea.less
index 1484fa7..4da9bdb 100644
--- a/src/css/textarea.less
+++ b/src/css/textarea.less
@@ -20,5 +20,10 @@
 
     width: 1px; // don't "stick out" invisibly from a math field,
     height: 1px; // can affect ancestor's .scroll{Width,Height}
+
+    // Needed to fix a Safari 10 bug where box-sizing: border-box is
+    // preventing text from being copied.
+    // https://github.com/mathquill/mathquill/issues/686
+    box-sizing: content-box;
   }
 }
diff --git a/src/tree.js b/src/tree.js
index 649c517..335dafa 100644
--- a/src/tree.js
+++ b/src/tree.js
@@ -156,6 +156,10 @@
   _.isEmpty = function() {
     return this.ends[L] === 0 && this.ends[R] === 0;
   };
+  
+  _.isStyleBlock = function() {
+    return false;
+  };
 
   _.children = function() {
     return Fragment(this.ends[L], this.ends[R]);
diff --git a/test/unit/css.test.js b/test/unit/css.test.js
index 639cdf9..56e12d2 100644
--- a/test/unit/css.test.js
+++ b/test/unit/css.test.js
@@ -82,6 +82,37 @@
     $(mq.el()).remove();
   });
 
+  test('proper unary/binary within style block', function () {
+    var mq = MQ.MathField($('<span></span>').appendTo('#mock')[0]);
+    mq.latex('\\class{dummy}{-}2\\class{dummy}{+}4');
+    var spans = $(mq.el()).find('.mq-root-block').find('span');
+    assert.equal(spans.length, 6, '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'); }
+
+    assertUnaryOperator(1, '\\class{dummy}{-}');
+    assertBinaryOperator(4, '\\class{dummy}{-}2\\class{dummy}{+}');
+
+    mq.latex('\\textcolor{red}{-}2\\textcolor{green}{+}4');
+    spans = $(mq.el()).find('.mq-root-block').find('span');
+    assert.equal(spans.length, 6, 'PlusMinus expression parsed incorrectly');
+
+    assertUnaryOperator(1, '\\textcolor{red}{-}');
+    assertBinaryOperator(4, '\\textcolor{red}{-}2\\textcolor{green}{+}');
+
+    //test recursive depths
+    mq.latex('\\textcolor{red}{\\class{dummy}{-}}2\\textcolor{green}{\\class{dummy}{+}}4');
+    spans = $(mq.el()).find('.mq-root-block').find('span');
+    assert.equal(spans.length, 8, 'PlusMinus expression parsed incorrectly');
+
+    assertUnaryOperator(2, '\\textcolor{red}{\\class{dummy}{-}}');
+    assertBinaryOperator(6, '\\textcolor{red}{\\class{dummy}{-}}2\\textcolor{green}{\\class{dummy}{+}}');
+
+    $(mq.el()).remove();
+  });
+
   test('operator name spacing e.g. sin x', function() {
     var mq = MathQuill.MathField($('<span></span>').appendTo(mock)[0]);