diff --git a/core/block.js b/core/block.js
index 96c54443..7e4db24d 100644
--- a/core/block.js
+++ b/core/block.js
@@ -81,13 +81,13 @@ Blockly.Block = function(workspace, prototypeName, opt_id) {
 
   /**
    * @type {Blockly.Block}
-   * @private
+   * @protected
    */
   this.parentBlock_ = null;
 
   /**
    * @type {!Array.<!Blockly.Block>}
-   * @private
+   * @protected
    */
   this.childBlocks_ = [];
 
@@ -117,7 +117,7 @@ Blockly.Block = function(workspace, prototypeName, opt_id) {
 
   /**
    * @type {boolean}
-   * @private
+   * @protected
    */
   this.collapsed_ = false;
 
@@ -317,7 +317,7 @@ Blockly.Block.prototype.initModel = function() {
 /**
  * Unplug this block from its superior block.  If this block is a statement,
  * optionally reconnect the block underneath with the block on top.
- * @param {boolean} opt_healStack Disconnect child statement and reconnect
+ * @param {boolean=} opt_healStack Disconnect child statement and reconnect
  *   stack.  Defaults to false.
  */
 Blockly.Block.prototype.unplug = function(opt_healStack) {
@@ -393,7 +393,7 @@ Blockly.Block.prototype.lastConnectionInStack = function() {
 /**
  * Bump unconnected blocks out of alignment.  Two blocks which aren't actually
  * connected should not coincidentally line up on screen.
- * @private
+ * @protected
  */
 Blockly.Block.prototype.bumpNeighbours_ = function() {
   console.warn('Not expected to reach this bumpNeighbours_ function. The ' +
@@ -949,7 +949,7 @@ Blockly.Block.prototype.setFieldValue = function(newValue, name) {
 /**
  * Set whether this block can chain onto the bottom of another block.
  * @param {boolean} newBoolean True if there can be a previous statement.
- * @param {string|Array.<string>|null|undefined} opt_check Statement type or
+ * @param {(string|Array.<string>|null)=} opt_check Statement type or
  *     list of statement types.  Null/undefined if any type could be connected.
  */
 Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) {
@@ -977,7 +977,7 @@ Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) {
 /**
  * Set whether another block can chain onto the bottom of this block.
  * @param {boolean} newBoolean True if there can be a next statement.
- * @param {string|Array.<string>|null|undefined} opt_check Statement type or
+ * @param {(string|Array.<string>|null)=} opt_check Statement type or
  *     list of statement types.  Null/undefined if any type could be connected.
  */
 Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) {
@@ -1002,7 +1002,7 @@ Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) {
 /**
  * Set whether this block returns a value.
  * @param {boolean} newBoolean True if there is an output.
- * @param {string|Array.<string>|null|undefined} opt_check Returned type or list
+ * @param {(string|Array.<string>|null)=} opt_check Returned type or list
  *     of returned types.  Null or undefined if any type could be returned
  *     (e.g. variable get).
  */
@@ -1451,7 +1451,7 @@ Blockly.Block.prototype.interpolate_ = function(message, args, lastDummyAlign) {
  * @param {string} name Language-neutral identifier which may used to find this
  *     input again.  Should be unique to this block.
  * @return {!Blockly.Input} The input object created.
- * @private
+ * @protected
  */
 Blockly.Block.prototype.appendInput_ = function(type, name) {
   var connection = null;
diff --git a/core/block_svg.js b/core/block_svg.js
index 663095cc..d2e6f096 100644
--- a/core/block_svg.js
+++ b/core/block_svg.js
@@ -48,7 +48,7 @@ goog.require('goog.userAgent');
  * @param {?string} prototypeName Name of the language object containing
  *     type-specific functions for this block.
  * @param {string=} opt_id Optional ID.  Use this ID if provided, otherwise
- *     create a new id.
+ *     create a new ID.
  * @extends {Blockly.Block}
  * @constructor
  */
@@ -60,7 +60,8 @@ Blockly.BlockSvg = function(workspace, prototypeName, opt_id) {
    */
   this.svgGroup_ = Blockly.utils.createSvgElement('g', {}, null);
   /** @type {SVGElement} */
-  this.svgPath_ = Blockly.utils.createSvgElement('path', {'class': 'blocklyPath blocklyBlockBackground'},
+  this.svgPath_ = Blockly.utils.createSvgElement('path',
+      {'class': 'blocklyPath blocklyBlockBackground'},
       this.svgGroup_);
   this.svgPath_.tooltip = this;
 
@@ -154,8 +155,8 @@ Blockly.BlockSvg.prototype.initSvg = function() {
   this.updateColour();
   this.updateMovable();
   if (!this.workspace.options.readOnly && !this.eventsInit_) {
-    Blockly.bindEventWithChecks_(this.getSvgRoot(), 'mousedown', this,
-                       this.onMouseDown_);
+    Blockly.bindEventWithChecks_(
+        this.getSvgRoot(), 'mousedown', this, this.onMouseDown_);
   }
   this.eventsInit_ = true;
 
@@ -598,7 +599,7 @@ Blockly.BlockSvg.prototype.tab = function(start, forward) {
 
 /**
  * Create an ordered list of all text fields and connected inputs.
- * @return {!Array<!Blockly.FieldTextInput|!Blockly.Input>} The ordered list.
+ * @return {!Array.<!Blockly.FieldTextInput|!Blockly.Input>} The ordered list.
  * @private
  */
 Blockly.BlockSvg.prototype.createTabList_ = function() {
@@ -815,12 +816,12 @@ Blockly.BlockSvg.prototype.setDragging = function(adding) {
     group.skew_ = '';
     Blockly.draggingConnections_ =
         Blockly.draggingConnections_.concat(this.getConnections_(true));
-    Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
-                      'blocklyDragging');
+    Blockly.utils.addClass(
+        /** @type {!Element} */ (this.svgGroup_), 'blocklyDragging');
   } else {
     Blockly.draggingConnections_ = [];
-    Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
-                         'blocklyDragging');
+    Blockly.utils.removeClass(
+        /** @type {!Element} */ (this.svgGroup_), 'blocklyDragging');
   }
   // Recurse through all blocks attached under this one.
   for (var i = 0; i < this.childBlocks_.length; i++) {
@@ -833,11 +834,11 @@ Blockly.BlockSvg.prototype.setDragging = function(adding) {
  */
 Blockly.BlockSvg.prototype.updateMovable = function() {
   if (this.isMovable()) {
-    Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
-                      'blocklyDraggable');
+    Blockly.utils.addClass(
+        /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggable');
   } else {
-    Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
-                         'blocklyDraggable');
+    Blockly.utils.removeClass(
+        /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggable');
   }
 };
 
@@ -1076,16 +1077,16 @@ Blockly.BlockSvg.prototype.setMutator = function(mutator) {
  * Select this block.  Highlight it visually.
  */
 Blockly.BlockSvg.prototype.addSelect = function() {
-  Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
-                    'blocklySelected');
+  Blockly.utils.addClass(
+      /** @type {!Element} */ (this.svgGroup_), 'blocklySelected');
 };
 
 /**
  * Unselect this block.  Remove its highlighting.
  */
 Blockly.BlockSvg.prototype.removeSelect = function() {
-  Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
-                       'blocklySelected');
+  Blockly.utils.removeClass(
+      /** @type {!Element} */ (this.svgGroup_),  'blocklySelected');
 };
 
 /**
@@ -1112,11 +1113,11 @@ Blockly.BlockSvg.prototype.setMouseThroughStyle = function(letMouseThrough) {
  */
 Blockly.BlockSvg.prototype.setDeleteStyle = function(enable) {
   if (enable) {
-    Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
-        'blocklyDraggingDelete');
+    Blockly.utils.addClass(
+        /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggingDelete');
   } else {
-    Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
-        'blocklyDraggingDelete');
+    Blockly.utils.removeClass(
+        /** @type {!Element} */ (this.svgGroup_), 'blocklyDraggingDelete');
   }
 };
 
@@ -1143,8 +1144,8 @@ Blockly.BlockSvg.prototype.setColour = function(colour, colourSecondary,
 
 /**
  * Move this block to the front of the visible workspace.
- * <g> tags do not respect z-index so svg renders them in the
- * order that they are in the dom.  By placing this block first within the
+ * <g> tags do not respect z-index so SVG renders them in the
+ * order that they are in the DOM.  By placing this block first within the
  * block group's <g>, it will render on top of any other blocks.
  * @package
  */
@@ -1160,7 +1161,7 @@ Blockly.BlockSvg.prototype.bringToFront = function() {
 /**
  * Set whether this block can chain onto the bottom of another block.
  * @param {boolean} newBoolean True if there can be a previous statement.
- * @param {string|Array.<string>|null|undefined} opt_check Statement type or
+ * @param {(string|Array.<string>|null)=} opt_check Statement type or
  *     list of statement types.  Null/undefined if any type could be connected.
  */
 Blockly.BlockSvg.prototype.setPreviousStatement =
@@ -1178,7 +1179,7 @@ Blockly.BlockSvg.prototype.setPreviousStatement =
 /**
  * Set whether another block can chain onto the bottom of this block.
  * @param {boolean} newBoolean True if there can be a next statement.
- * @param {string|Array.<string>|null|undefined} opt_check Statement type or
+ * @param {(string|Array.<string>|null)=} opt_check Statement type or
  *     list of statement types.  Null/undefined if any type could be connected.
  */
 Blockly.BlockSvg.prototype.setNextStatement = function(newBoolean, opt_check) {
@@ -1194,7 +1195,7 @@ Blockly.BlockSvg.prototype.setNextStatement = function(newBoolean, opt_check) {
 /**
  * Set whether this block returns a value.
  * @param {boolean} newBoolean True if there is an output.
- * @param {string|Array.<string>|null|undefined} opt_check Returned type or list
+ * @param {(string|Array.<string>|null)=} opt_check Returned type or list
  *     of returned types.  Null or undefined if any type could be returned
  *     (e.g. variable get).
  */
diff --git a/core/blockly.js b/core/blockly.js
index 8cc172cb..32d4efdb 100644
--- a/core/blockly.js
+++ b/core/blockly.js
@@ -386,19 +386,18 @@ Blockly.defineBlocksWithJsonArray = function(jsonArray) {
  * Bind an event to a function call.  When calling the function, verifies that
  * it belongs to the touch stream that is currently being processed, and splits
  * multitouch events into multiple events as needed.
- * @param {!Node} node Node upon which to listen.
+ * @param {!EventTarget} node Node upon which to listen.
  * @param {string} name Event name to listen to (e.g. 'mousedown').
  * @param {Object} thisObject The value of 'this' in the function.
  * @param {!Function} func Function to call when event is triggered.
- * @param {boolean} opt_noCaptureIdentifier True if triggering on this event
+ * @param {boolean=} opt_noCaptureIdentifier True if triggering on this event
  *     should not block execution of other event handlers on this touch or other
  *     simultaneous touches.
- * @param {boolean} opt_noPreventDefault True if triggering on this event
+ * @param {boolean=} opt_noPreventDefault True if triggering on this event
  *     should prevent the default handler.  False by default.  If
  *     opt_noPreventDefault is provided, opt_noCaptureIdentifier must also be
  *     provided.
  * @return {!Array.<!Array>} Opaque data that can be passed to unbindEvent_.
- * @private
  */
 Blockly.bindEventWithChecks_ = function(node, name, thisObject, func,
     opt_noCaptureIdentifier, opt_noPreventDefault) {
@@ -452,7 +451,7 @@ Blockly.bindEventWithChecks_ = function(node, name, thisObject, func,
  * simultaneous event processing.
  * @deprecated in favor of bindEventWithChecks_, but preserved for external
  * users.
- * @param {!Node} node Node upon which to listen.
+ * @param {!EventTarget} node Node upon which to listen.
  * @param {string} name Event name to listen to (e.g. 'mousedown').
  * @param {Object} thisObject The value of 'this' in the function.
  * @param {!Function} func Function to call when event is triggered.
diff --git a/core/blocks.js b/core/blocks.js
index 5b78050a..c27be1d4 100644
--- a/core/blocks.js
+++ b/core/blocks.js
@@ -32,6 +32,6 @@ goog.provide('Blockly.Blocks');
 
 /*
  * A mapping of block type names to block prototype objects.
- * @type {!Object<string,Object>}
+ * @type {!Object.<string,Object>}
  */
 Blockly.Blocks = new Object(null);
diff --git a/core/bubble.js b/core/bubble.js
index 1cd9443f..56bb8b44 100644
--- a/core/bubble.js
+++ b/core/bubble.js
@@ -40,14 +40,14 @@ goog.require('goog.userAgent');
  *     bubble.
  * @param {!Element} content SVG content for the bubble.
  * @param {Element} shape SVG element to avoid eclipsing.
- * @param {!goog.math.Coodinate} anchorXY Absolute position of bubble's anchor
+ * @param {!goog.math.Coordinate} anchorXY Absolute position of bubble's anchor
  *     point.
  * @param {?number} bubbleWidth Width of bubble, or null if not resizable.
  * @param {?number} bubbleHeight Height of bubble, or null if not resizable.
  * @constructor
  */
 Blockly.Bubble = function(workspace, content, shape, anchorXY,
-                          bubbleWidth, bubbleHeight) {
+    bubbleWidth, bubbleHeight) {
   this.workspace_ = workspace;
   this.content_ = content;
   this.shape_ = shape;
@@ -75,11 +75,11 @@ Blockly.Bubble = function(workspace, content, shape, anchorXY,
   this.rendered_ = true;
 
   if (!workspace.options.readOnly) {
-    Blockly.bindEventWithChecks_(this.bubbleBack_, 'mousedown', this,
-                       this.bubbleMouseDown_);
+    Blockly.bindEventWithChecks_(
+        this.bubbleBack_, 'mousedown', this, this.bubbleMouseDown_);
     if (this.resizeGroup_) {
-      Blockly.bindEventWithChecks_(this.resizeGroup_, 'mousedown', this,
-                         this.resizeMouseDown_);
+      Blockly.bindEventWithChecks_(
+          this.resizeGroup_, 'mousedown', this, this.resizeMouseDown_);
     }
   }
 };
@@ -162,14 +162,15 @@ Blockly.Bubble.bubbleMouseUp_ = function(/*e*/) {
 Blockly.Bubble.prototype.rendered_ = false;
 
 /**
- * Absolute coordinate of anchor point.
+ * Absolute coordinate of anchor point, in workspace coordinates
  * @type {goog.math.Coordinate}
  * @private
  */
 Blockly.Bubble.prototype.anchorXY_ = null;
 
 /**
- * Relative X coordinate of bubble with respect to the anchor's centre.
+ * Relative X coordinate of bubble with respect to the anchor's centre,
+ * in workspace units.
  * In RTL mode the initial value is negated.
  * @private
  */
@@ -235,8 +236,13 @@ Blockly.Bubble.prototype.createDom_ = function(content, hasResize) {
       filter, this.bubbleGroup_);
   this.bubbleArrow_ = Blockly.utils.createSvgElement('path', {}, bubbleEmboss);
   this.bubbleBack_ = Blockly.utils.createSvgElement('rect',
-      {'class': 'blocklyDraggable', 'x': 0, 'y': 0,
-      'rx': Blockly.Bubble.BORDER_WIDTH, 'ry': Blockly.Bubble.BORDER_WIDTH},
+      {
+        'class': 'blocklyDraggable',
+        'x': 0,
+        'y': 0,
+        'rx': Blockly.Bubble.BORDER_WIDTH,
+        'ry': Blockly.Bubble.BORDER_WIDTH
+      },
       bubbleEmboss);
   if (hasResize) {
     this.resizeGroup_ = Blockly.utils.createSvgElement('g',
@@ -248,13 +254,21 @@ Blockly.Bubble.prototype.createDom_ = function(content, hasResize) {
         {'points': '0,x x,x x,0'.replace(/x/g, resizeSize.toString())},
         this.resizeGroup_);
     Blockly.utils.createSvgElement('line',
-        {'class': 'blocklyResizeLine',
-        'x1': resizeSize / 3, 'y1': resizeSize - 1,
-        'x2': resizeSize - 1, 'y2': resizeSize / 3}, this.resizeGroup_);
+        {
+          'class': 'blocklyResizeLine',
+          'x1': resizeSize / 3,
+          'y1': resizeSize - 1,
+          'x2': resizeSize - 1,
+          'y2': resizeSize / 3
+        }, this.resizeGroup_);
     Blockly.utils.createSvgElement('line',
-        {'class': 'blocklyResizeLine',
-        'x1': resizeSize * 2 / 3, 'y1': resizeSize - 1,
-        'x2': resizeSize - 1, 'y2': resizeSize * 2 / 3}, this.resizeGroup_);
+        {
+          'class': 'blocklyResizeLine',
+          'x1': resizeSize * 2 / 3,
+          'y1': resizeSize - 1,
+          'x2': resizeSize - 1,
+          'y2': resizeSize * 2 / 3
+        }, this.resizeGroup_);
   } else {
     this.resizeGroup_ = null;
   }
diff --git a/core/comment.js b/core/comment.js
index 83d264c6..fe0dbc83 100644
--- a/core/comment.js
+++ b/core/comment.js
@@ -70,21 +70,27 @@ Blockly.Comment.prototype.drawIcon_ = function(group) {
   // Circle.
   Blockly.utils.createSvgElement('circle',
       {'class': 'blocklyIconShape', 'r': '8', 'cx': '8', 'cy': '8'},
-       group);
+      group);
   // Can't use a real '?' text character since different browsers and operating
   // systems render it differently.
   // Body of question mark.
   Blockly.utils.createSvgElement('path',
-      {'class': 'blocklyIconSymbol',
-       'd': 'm6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.405' +
-       ' 0.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25' +
-       ' -1.201,0.998 -1.201,1.528 -1.204,2.19z'},
-       group);
+      {
+        'class': 'blocklyIconSymbol',
+        'd': 'm6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.405' +
+          '0.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25' +
+          '-1.201,0.998 -1.201,1.528 -1.204,2.19z'},
+      group);
   // Dot of question mark.
   Blockly.utils.createSvgElement('rect',
-      {'class': 'blocklyIconSymbol',
-       'x': '6.8', 'y': '10.78', 'height': '2', 'width': '2'},
-       group);
+      {
+        'class': 'blocklyIconSymbol',
+        'x': '6.8',
+        'y': '10.78',
+        'height': '2',
+        'width': '2'
+      },
+      group);
 };
 
 /**
@@ -260,7 +266,7 @@ Blockly.Comment.prototype.getText = function() {
 Blockly.Comment.prototype.setText = function(text) {
   if (this.text_ != text) {
     Blockly.Events.fire(new Blockly.Events.BlockChange(
-      this.block_, 'comment', null, this.text_, text));
+        this.block_, 'comment', null, this.text_, text));
     this.text_ = text;
   }
   if (this.textarea_) {
diff --git a/core/connection.js b/core/connection.js
index fedacf4e..fad934db 100644
--- a/core/connection.js
+++ b/core/connection.js
@@ -39,7 +39,7 @@ goog.require('goog.dom');
 Blockly.Connection = function(source, type) {
   /**
    * @type {!Blockly.Block}
-   * @private
+   * @protected
    */
   this.sourceBlock_ = source;
   /** @type {number} */
@@ -89,28 +89,28 @@ Blockly.Connection.prototype.shadowDom_ = null;
 /**
  * Horizontal location of this connection.
  * @type {number}
- * @private
+ * @protected
  */
 Blockly.Connection.prototype.x_ = 0;
 
 /**
  * Vertical location of this connection.
  * @type {number}
- * @private
+ * @protected
  */
 Blockly.Connection.prototype.y_ = 0;
 
 /**
  * Has this connection been added to the connection database?
  * @type {boolean}
- * @private
+ * @protected
  */
 Blockly.Connection.prototype.inDB_ = false;
 
 /**
  * Connection database for connections of this type on the current workspace.
  * @type {Blockly.ConnectionDB}
- * @private
+ * @protected
  */
 Blockly.Connection.prototype.db_ = null;
 
@@ -118,14 +118,14 @@ Blockly.Connection.prototype.db_ = null;
  * Connection database for connections compatible with this type on the
  * current workspace.
  * @type {Blockly.ConnectionDB}
- * @private
+ * @protected
  */
 Blockly.Connection.prototype.dbOpposite_ = null;
 
 /**
  * Whether this connections is hidden (not tracked in a database) or not.
  * @type {boolean}
- * @private
+ * @protected
  */
 Blockly.Connection.prototype.hidden_ = null;
 
@@ -133,7 +133,7 @@ Blockly.Connection.prototype.hidden_ = null;
  * Connect two connections together.  This is the connection on the superior
  * block.
  * @param {!Blockly.Connection} childConnection Connection on inferior block.
- * @private
+ * @protected
  */
 Blockly.Connection.prototype.connect_ = function(childConnection) {
   var parentConnection = this;
@@ -537,7 +537,7 @@ Blockly.Connection.singleConnection_ = function(block, orphanBlock) {
     if (thisConnection && thisConnection.type == Blockly.INPUT_VALUE &&
         orphanBlock.outputConnection.checkType_(thisConnection)) {
       if (connection) {
-        return null;  // More than   one connection.
+        return null;  // More than one connection.
       }
       connection = thisConnection;
     }
@@ -574,7 +574,7 @@ Blockly.Connection.prototype.disconnect = function() {
  * Disconnect two blocks that are connected by this connection.
  * @param {!Blockly.Block} parentBlock The superior block.
  * @param {!Blockly.Block} childBlock The inferior block.
- * @private
+ * @protected
  */
 Blockly.Connection.prototype.disconnectInternal_ = function(parentBlock,
     childBlock) {
@@ -594,7 +594,7 @@ Blockly.Connection.prototype.disconnectInternal_ = function(parentBlock,
 
 /**
  * Respawn the shadow block if there was one connected to the this connection.
- * @private
+ * @protected
  */
 Blockly.Connection.prototype.respawnShadow_ = function() {
   var parentBlock = this.getSourceBlock();
@@ -628,7 +628,7 @@ Blockly.Connection.prototype.targetBlock = function() {
  * value type system.  E.g. square_root("Hello") is not compatible.
  * @param {!Blockly.Connection} otherConnection Connection to compare against.
  * @return {boolean} True if the connections share a type.
- * @private
+ * @protected
  */
 Blockly.Connection.prototype.checkType_ = function(otherConnection) {
   if (!this.check_ || !otherConnection.check_) {
diff --git a/core/connection_db.js b/core/connection_db.js
index 8b3c3008..acb044cf 100644
--- a/core/connection_db.js
+++ b/core/connection_db.js
@@ -109,9 +109,8 @@ Blockly.ConnectionDB.prototype.findConnection = function(conn) {
  * @return {number} The candidate index.
  * @private
  */
-Blockly.ConnectionDB.prototype.findPositionForConnection_ =
-    function(connection) {
-  /* eslint-disable indent */
+Blockly.ConnectionDB.prototype.findPositionForConnection_ = function(
+    connection) {
   if (!this.length) {
     return 0;
   }
@@ -129,7 +128,7 @@ Blockly.ConnectionDB.prototype.findPositionForConnection_ =
     }
   }
   return pointerMin;
-};  /* eslint-enable indent */
+};
 
 /**
  * Remove a connection from the database.  Must already exist in DB.
diff --git a/core/contextmenu.js b/core/contextmenu.js
index e65b918c..28f30318 100644
--- a/core/contextmenu.js
+++ b/core/contextmenu.js
@@ -67,8 +67,8 @@ Blockly.ContextMenu.show = function(e, options, rtl) {
   }
   var menu = Blockly.ContextMenu.populate_(options, rtl);
 
-  goog.events.listen(menu, goog.ui.Component.EventType.ACTION,
-                     Blockly.ContextMenu.hide);
+  goog.events.listen(
+      menu, goog.ui.Component.EventType.ACTION, Blockly.ContextMenu.hide);
 
   Blockly.ContextMenu.position_(menu, e, rtl);
   // 1ms delay is required for focusing on context menus because some other
@@ -98,8 +98,8 @@ Blockly.ContextMenu.populate_ = function(options, rtl) {
     menu.addChild(menuItem, true);
     menuItem.setEnabled(option.enabled);
     if (option.enabled) {
-      goog.events.listen(menuItem, goog.ui.Component.EventType.ACTION,
-                         option.callback);
+      goog.events.listen(
+          menuItem, goog.ui.Component.EventType.ACTION, option.callback);
       menuItem.handleContextMenu = function(/* e */) {
         // Right-clicking on menu option should count as a click.
         goog.events.dispatchEvent(this, goog.ui.Component.EventType.ACTION);
@@ -154,8 +154,8 @@ Blockly.ContextMenu.createWidget_ = function(menu) {
   var menuDom = menu.getElement();
   Blockly.utils.addClass(menuDom, 'blocklyContextMenu');
   // Prevent system context menu when right-clicking a Blockly context menu.
-  Blockly.bindEventWithChecks_(menuDom, 'contextmenu', null,
-                               Blockly.utils.noEvent);
+  Blockly.bindEventWithChecks_(
+      menuDom, 'contextmenu', null, Blockly.utils.noEvent);
   // Enable autofocus after the initial render to avoid issue #1329.
   menu.setAllowAutoFocus(true);
 };
diff --git a/core/extensions.js b/core/extensions.js
index 3ea2fb31..983c3876 100644
--- a/core/extensions.js
+++ b/core/extensions.js
@@ -99,13 +99,13 @@ Blockly.Extensions.registerMutator = function(name, mixinObj, opt_helperFn,
   var errorPrefix = 'Error when registering mutator "' + name + '": ';
 
   // Sanity check the mixin object before registering it.
-  Blockly.Extensions.checkHasFunction_(errorPrefix, mixinObj.domToMutation,
-                                       'domToMutation');
-  Blockly.Extensions.checkHasFunction_(errorPrefix, mixinObj.mutationToDom,
-                                       'mutationToDom');
+  Blockly.Extensions.checkHasFunction_(
+      errorPrefix, mixinObj.domToMutation, 'domToMutation');
+  Blockly.Extensions.checkHasFunction_(
+      errorPrefix, mixinObj.mutationToDom, 'mutationToDom');
 
-  var hasMutatorDialog = Blockly.Extensions.checkMutatorDialog_(mixinObj,
-    errorPrefix);
+  var hasMutatorDialog =
+      Blockly.Extensions.checkMutatorDialog_(mixinObj, errorPrefix);
 
   if (opt_helperFn && !goog.isFunction(opt_helperFn)) {
     throw new Error('Extension "' + name + '" is not a function');
@@ -313,11 +313,12 @@ Blockly.Extensions.mutatorPropertiesMatch_ = function(oldProperties, block) {
  * reported as warnings in the console, and are never fatal.
  * @param {string} dropdownName The name of the field whose value is the key
  *     to the lookup table.
- * @param {!Object<string, string>} lookupTable The table of field values to
+ * @param {!Object.<string, string>} lookupTable The table of field values to
  *     tooltip text.
  * @return {Function} The extension function.
  */
-Blockly.Extensions.buildTooltipForDropdown = function(dropdownName, lookupTable) {
+Blockly.Extensions.buildTooltipForDropdown = function(dropdownName,
+    lookupTable) {
   // List of block types already validated, to minimize duplicate warnings.
   var blockTypesChecked = [];
 
diff --git a/core/flyout_base.js b/core/flyout_base.js
index 92b69e23..c6d2c952 100644
--- a/core/flyout_base.js
+++ b/core/flyout_base.js
@@ -71,7 +71,7 @@ Blockly.Flyout = function(workspaceOptions) {
   /**
    * Position of the toolbox and flyout relative to the workspace.
    * @type {number}
-   * @private
+   * @protected
    */
   this.toolboxPosition_ = workspaceOptions.toolboxPosition;
 
@@ -93,7 +93,7 @@ Blockly.Flyout = function(workspaceOptions) {
   /**
    * List of visible buttons.
    * @type {!Array.<!Blockly.FlyoutButton>}
-   * @private
+   * @protected
    */
   this.buttons_ = [];
 
@@ -188,14 +188,14 @@ Blockly.Flyout.prototype.SCROLLBAR_PADDING = 2;
 /**
  * Width of flyout.
  * @type {number}
- * @private
+ * @protected
  */
 Blockly.Flyout.prototype.width_ = 0;
 
 /**
  * Height of flyout.
  * @type {number}
- * @private
+ * @protected
  */
 Blockly.Flyout.prototype.height_ = 0;
 
@@ -234,7 +234,7 @@ Blockly.Flyout.prototype.verticalOffset_ = 0;
  * This is used to know when to create a new block and when to scroll the
  * flyout. Setting it to 360 means that all drags create a new block.
  * @type {number}
- * @private
+ * @protected
 */
 Blockly.Flyout.prototype.dragAngleRange_ = 70;
 
@@ -264,7 +264,7 @@ Blockly.Flyout.prototype.createDom = function(tagName) {
   // Setting style to display:none to start. The toolbox and flyout
   // hide/show code will set up proper visibility and size later.
   this.svgGroup_ = Blockly.utils.createSvgElement(tagName,
-      {'class': 'blocklyFlyout', 'style' : 'display: none'}, null);
+      {'class': 'blocklyFlyout', 'style': 'display: none'}, null);
   this.svgBackground_ = Blockly.utils.createSvgElement('path',
       {'class': 'blocklyFlyoutBackground'}, this.svgGroup_);
   this.svgGroup_.appendChild(this.workspace_.createDom());
@@ -289,7 +289,8 @@ Blockly.Flyout.prototype.init = function(targetWorkspace) {
       Blockly.bindEventWithChecks_(this.svgGroup_, 'wheel', this, this.wheel_));
   // Dragging the flyout up and down (or left and right).
   Array.prototype.push.apply(this.eventWrappers_,
-      Blockly.bindEventWithChecks_(this.svgGroup_, 'mousedown', this, this.onMouseDown_));
+      Blockly.bindEventWithChecks_(
+          this.svgBackground_, 'mousedown', this, this.onMouseDown_));
 
   // A flyout connected to a workspace doesn't have its own current gesture.
   this.workspace_.getGesture =
diff --git a/core/flyout_button.js b/core/flyout_button.js
index e60cb4dd..e8db4052 100644
--- a/core/flyout_button.js
+++ b/core/flyout_button.js
@@ -194,7 +194,7 @@ Blockly.FlyoutButton.prototype.show = function() {
 };
 
 /**
- * Update svg attributes to match internal state.
+ * Update SVG attributes to match internal state.
  * @private
  */
 Blockly.FlyoutButton.prototype.updateTransform_ = function() {
diff --git a/core/grid.js b/core/grid.js
index e87df602..781bf229 100644
--- a/core/grid.js
+++ b/core/grid.js
@@ -121,7 +121,7 @@ Blockly.Grid.prototype.getSpacing = function() {
 /**
  * Get the id of the pattern element, which should be randomized to avoid
  * conflicts with other Blockly instances on the page.
- * @return {string} The pattern id.
+ * @return {string} The pattern ID.
  * @package
  */
 Blockly.Grid.prototype.getPatternId = function() {
@@ -207,8 +207,10 @@ Blockly.Grid.createDom = function(rnd, gridOptions, defs) {
     </pattern>
   */
   var gridPattern = Blockly.utils.createSvgElement('pattern',
-      {'id': 'blocklyGridPattern' + rnd,
-       'patternUnits': 'userSpaceOnUse'}, defs);
+      {
+        'id': 'blocklyGridPattern' + rnd,
+        'patternUnits': 'userSpaceOnUse'
+      }, defs);
   if (gridOptions['length'] > 0 && gridOptions['spacing'] > 0) {
     Blockly.utils.createSvgElement('line',
         {'stroke': gridOptions['colour']}, gridPattern);
@@ -217,6 +219,9 @@ Blockly.Grid.createDom = function(rnd, gridOptions, defs) {
           {'stroke': gridOptions['colour']}, gridPattern);
     }
     // x1, y1, x1, x2 properties will be set later in update.
+  } else {
+    // Edge 16 doesn't handle empty patterns
+    Blockly.utils.createSvgElement('line', {}, gridPattern);
   }
   return gridPattern;
 };
diff --git a/core/icon.js b/core/icon.js
index 37dd6768..b51d90ef 100644
--- a/core/icon.js
+++ b/core/icon.js
@@ -52,14 +52,14 @@ Blockly.Icon.prototype.SIZE = 17;
 /**
  * Bubble UI (if visible).
  * @type {Blockly.Bubble}
- * @private
+ * @protected
  */
 Blockly.Icon.prototype.bubble_ = null;
 
 /**
  * Absolute coordinate of icon's center.
  * @type {goog.math.Coordinate}
- * @private
+ * @protected
  */
 Blockly.Icon.prototype.iconXY_ = null;
 
@@ -79,14 +79,14 @@ Blockly.Icon.prototype.createIcon = function() {
   this.iconGroup_ = Blockly.utils.createSvgElement('g',
       {'class': 'blocklyIconGroup'}, null);
   if (this.block_.isInFlyout) {
-    Blockly.utils.addClass(/** @type {!Element} */ (this.iconGroup_),
-                      'blocklyIconGroupReadonly');
+    Blockly.utils.addClass(
+        /** @type {!Element} */ (this.iconGroup_), 'blocklyIconGroupReadonly');
   }
   this.drawIcon_(this.iconGroup_);
 
   this.block_.getSvgRoot().appendChild(this.iconGroup_);
-  Blockly.bindEventWithChecks_(this.iconGroup_, 'mouseup', this,
-      this.iconClick_);
+  Blockly.bindEventWithChecks_(
+      this.iconGroup_, 'mouseup', this, this.iconClick_);
   this.updateEditable();
 };
 
@@ -119,7 +119,7 @@ Blockly.Icon.prototype.isVisible = function() {
 /**
  * Clicking on the icon toggles if the bubble is visible.
  * @param {!Event} e Mouse click event.
- * @private
+ * @protected
  */
 Blockly.Icon.prototype.iconClick_ = function(e) {
   if (this.block_.workspace.isDragging()) {
diff --git a/core/mutator.js b/core/mutator.js
index e4abf5fc..548f2c3c 100644
--- a/core/mutator.js
+++ b/core/mutator.js
@@ -159,15 +159,17 @@ Blockly.Mutator.prototype.updateEditable = function() {
   if (!this.block_.isInFlyout) {
     if (this.block_.isEditable()) {
       if (this.iconGroup_) {
-        Blockly.utils.removeClass(/** @type {!Element} */ (this.iconGroup_),
-                             'blocklyIconGroupReadonly');
+        Blockly.utils.removeClass(
+            /** @type {!Element} */ (this.iconGroup_),
+            'blocklyIconGroupReadonly');
       }
     } else {
       // Close any mutator bubble.  Icon is not clickable.
       this.setVisible(false);
       if (this.iconGroup_) {
-        Blockly.utils.addClass(/** @type {!Element} */ (this.iconGroup_),
-                          'blocklyIconGroupReadonly');
+        Blockly.utils.addClass(
+            /** @type {!Element} */ (this.iconGroup_),
+            'blocklyIconGroupReadonly');
       }
     }
   }
@@ -202,8 +204,8 @@ Blockly.Mutator.prototype.resizeBubble_ = function() {
     this.workspaceWidth_ = width;
     this.workspaceHeight_ = height;
     // Resize the bubble.
-    this.bubble_.setBubbleSize(width + doubleBorderWidth,
-                               height + doubleBorderWidth);
+    this.bubble_.setBubbleSize(
+        width + doubleBorderWidth, height + doubleBorderWidth);
     this.svgDialog_.setAttribute('width', this.workspaceWidth_);
     this.svgDialog_.setAttribute('height', this.workspaceHeight_);
   }
diff --git a/core/names.js b/core/names.js
index 7b797729..b76978b6 100644
--- a/core/names.js
+++ b/core/names.js
@@ -176,6 +176,7 @@ Blockly.Names.prototype.safeName_ = function(name) {
   } else {
     // Unfortunately names in non-latin characters will look like
     // _E9_9F_B3_E4_B9_90 which is pretty meaningless.
+    // https://github.com/google/blockly/issues/1654
     name = encodeURI(name.replace(/ /g, '_')).replace(/[^\w]/g, '_');
     // Most languages don't allow names with leading numbers.
     if ('0123456789'.indexOf(name[0]) != -1) {
diff --git a/core/rendered_connection.js b/core/rendered_connection.js
index 366f250e..58c2cffa 100644
--- a/core/rendered_connection.js
+++ b/core/rendered_connection.js
@@ -199,11 +199,14 @@ Blockly.RenderedConnection.prototype.highlight = function() {
   var xy = this.sourceBlock_.getRelativeToSurfaceXY();
   var x = this.x_ - xy.x;
   var y = this.y_ - xy.y;
-  Blockly.Connection.highlightedPath_ = Blockly.utils.createSvgElement('path',
-      {'class': 'blocklyHighlightedConnectionPath',
-       'd': steps,
-       transform: 'translate(' + x + ',' + y + ')' +
-           (this.sourceBlock_.RTL ? ' scale(-1 1)' : '')},
+  Blockly.Connection.highlightedPath_ = Blockly.utils.createSvgElement(
+      'path',
+      {
+        'class': 'blocklyHighlightedConnectionPath',
+        'd': steps,
+        transform: 'translate(' + x + ',' + y + ')' +
+            (this.sourceBlock_.RTL ? ' scale(-1 1)' : '')
+      },
       this.sourceBlock_.getSvgRoot());
 };
 
diff --git a/core/scrollbar.js b/core/scrollbar.js
index 65422572..98d09715 100644
--- a/core/scrollbar.js
+++ b/core/scrollbar.js
@@ -30,6 +30,7 @@ goog.provide('Blockly.ScrollbarPair');
 goog.require('goog.dom');
 goog.require('goog.events');
 
+
 /**
  * A note on units: most of the numbers that are in CSS pixels are scaled if the
  * scrollbar is in a mutator.
@@ -42,14 +43,18 @@ goog.require('goog.events');
  */
 Blockly.ScrollbarPair = function(workspace) {
   this.workspace_ = workspace;
-  this.hScroll = new Blockly.Scrollbar(workspace, true, true,
-    'blocklyMainWorkspaceScrollbar');
-  this.vScroll = new Blockly.Scrollbar(workspace, false, true,
-    'blocklyMainWorkspaceScrollbar');
-  this.corner_ = Blockly.utils.createSvgElement('rect',
-      {'height': Blockly.Scrollbar.scrollbarThickness,
-      'width': Blockly.Scrollbar.scrollbarThickness,
-      'class': 'blocklyScrollbarBackground'}, null);
+  this.hScroll = new Blockly.Scrollbar(
+      workspace, true, true, 'blocklyMainWorkspaceScrollbar');
+  this.vScroll = new Blockly.Scrollbar(
+      workspace, false, true, 'blocklyMainWorkspaceScrollbar');
+  this.corner_ = Blockly.utils.createSvgElement(
+      'rect',
+      {
+        'height': Blockly.Scrollbar.scrollbarThickness,
+        'width': Blockly.Scrollbar.scrollbarThickness,
+        'class': 'blocklyScrollbarBackground'
+      },
+      null);
   Blockly.utils.insertAfter_(this.corner_, workspace.getBubbleCanvas());
 };
 
@@ -189,7 +194,7 @@ Blockly.ScrollbarPair.prototype.getRatio_ = function(handlePosition, viewSize) {
  * @param {!Blockly.Workspace} workspace Workspace to bind the scrollbar to.
  * @param {boolean} horizontal True if horizontal, false if vertical.
  * @param {boolean=} opt_pair True if scrollbar is part of a horiz/vert pair.
- * @param {string} opt_class A class to be applied to this scrollbar.
+ * @param {string=} opt_class A class to be applied to this scrollbar.
  * @constructor
  */
 Blockly.Scrollbar = function(workspace, horizontal, opt_pair, opt_class) {
@@ -201,7 +206,7 @@ Blockly.Scrollbar = function(workspace, horizontal, opt_pair, opt_class) {
   this.createDom_(opt_class);
 
   /**
-   * The upper left corner of the scrollbar's svg group in CSS pixels relative
+   * The upper left corner of the scrollbar's SVG group in CSS pixels relative
    * to the scrollbar's origin.  This is usually relative to the injection div
    * origin.
    * @type {goog.math.Coordinate}
@@ -209,24 +214,20 @@ Blockly.Scrollbar = function(workspace, horizontal, opt_pair, opt_class) {
    */
   this.position_ = new goog.math.Coordinate(0, 0);
 
+  // Store the thickness in a temp variable for readability.
+  var scrollbarThickness = Blockly.Scrollbar.scrollbarThickness;
   if (horizontal) {
-    this.svgBackground_.setAttribute('height',
-        Blockly.Scrollbar.scrollbarThickness);
-    this.outerSvg_.setAttribute('height',
-          Blockly.Scrollbar.scrollbarThickness);
-    this.svgHandle_.setAttribute('height',
-        Blockly.Scrollbar.scrollbarThickness - 5);
+    this.svgBackground_.setAttribute('height', scrollbarThickness);
+    this.outerSvg_.setAttribute('height', scrollbarThickness);
+    this.svgHandle_.setAttribute('height', scrollbarThickness - 5);
     this.svgHandle_.setAttribute('y', 2.5);
 
     this.lengthAttribute_ = 'width';
     this.positionAttribute_ = 'x';
   } else {
-    this.svgBackground_.setAttribute('width',
-        Blockly.Scrollbar.scrollbarThickness);
-    this.outerSvg_.setAttribute('width',
-       Blockly.Scrollbar.scrollbarThickness);
-    this.svgHandle_.setAttribute('width',
-        Blockly.Scrollbar.scrollbarThickness - 5);
+    this.svgBackground_.setAttribute('width', scrollbarThickness);
+    this.outerSvg_.setAttribute('width', scrollbarThickness);
+    this.svgHandle_.setAttribute('width', scrollbarThickness - 5);
     this.svgHandle_.setAttribute('x', 2.5);
 
     this.lengthAttribute_ = 'height';
@@ -392,7 +393,7 @@ Blockly.ScrollbarPair.prototype.setContainerVisible = function(visible) {
 };
 
 /**
- * Set the position of the scrollbar's svg group in CSS pixels relative to the
+ * Set the position of the scrollbar's SVG group in CSS pixels relative to the
  * scrollbar's origin.  This sets the scrollbar's location within the workspace.
  * @param {number} x The new x coordinate.
  * @param {number} y The new y coordinate.
@@ -593,7 +594,7 @@ Blockly.Scrollbar.prototype.resizeContentVertical = function(hostMetrics) {
 /**
  * Create all the DOM elements required for a scrollbar.
  * The resulting widget is not sized.
- * @param {string} opt_class A class to be applied to this scrollbar.
+ * @param {string=} opt_class A class to be applied to this scrollbar.
  * @private
  */
 Blockly.Scrollbar.prototype.createDom_ = function(opt_class) {
@@ -610,17 +611,21 @@ Blockly.Scrollbar.prototype.createDom_ = function(opt_class) {
   if (opt_class) {
     className += ' ' + opt_class;
   }
-  this.outerSvg_ = Blockly.utils.createSvgElement('svg', {'class': className},
-                                                  null);
+  this.outerSvg_ = Blockly.utils.createSvgElement(
+      'svg', {'class': className}, null);
   this.svgGroup_ = Blockly.utils.createSvgElement('g', {}, this.outerSvg_);
-  this.svgBackground_ = Blockly.utils.createSvgElement('rect',
-      {'class': 'blocklyScrollbarBackground'}, this.svgGroup_);
+  this.svgBackground_ = Blockly.utils.createSvgElement(
+      'rect', {'class': 'blocklyScrollbarBackground'}, this.svgGroup_);
   var radius = Math.floor((Blockly.Scrollbar.scrollbarThickness - 5) / 2);
-  this.svgHandle_ = Blockly.utils.createSvgElement('rect',
-      {'class': 'blocklyScrollbarHandle', 'rx': radius, 'ry': radius},
+  this.svgHandle_ = Blockly.utils.createSvgElement(
+      'rect',
+      {
+        'class': 'blocklyScrollbarHandle',
+        'rx': radius,
+        'ry': radius
+      },
       this.svgGroup_);
-  Blockly.utils.insertAfter_(this.outerSvg_,
-                                 this.workspace_.getParentSvg());
+  Blockly.utils.insertAfter_(this.outerSvg_, this.workspace_.getParentSvg());
 };
 
 /**
@@ -669,7 +674,7 @@ Blockly.Scrollbar.prototype.setVisible = function(visible) {
  * Update visibility of scrollbar based on whether it thinks it should
  * be visible and whether its containing workspace is visible.
  * We cannot rely on the containing workspace being hidden to hide us
- * because it is not necessarily our parent in the dom.
+ * because it is not necessarily our parent in the DOM.
  */
 Blockly.Scrollbar.prototype.updateDisplay_ = function() {
   var show = true;