GJSLinting

This commit is contained in:
Lewis Hemens 2014-02-23 19:06:09 +00:00
parent b977b8c174
commit 089e94ab55
6 changed files with 123 additions and 49 deletions

View File

@ -7,6 +7,7 @@ try {
goog.provide('ascii'); goog.provide('ascii');
throw 1; throw 1;
} catch (e) { } catch (e) {
/** type {Object} */
window.ascii = window.ascii || {}; window.ascii = window.ascii || {};
} }
@ -41,7 +42,7 @@ try {
/** @const */ var KEY_RIGHT = '<right>'; /** @const */ var KEY_RIGHT = '<right>';
// http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript // http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript
/** @const */ var TOUCH_ENABLED = /** @const */ var TOUCH_ENABLED =
'ontouchstart' in window || 'ontouchstart' in window ||
'onmsgesturechange' in window; 'onmsgesturechange' in window;
@ -106,7 +107,7 @@ ascii.Vector.prototype.scale = function(scale) {
/** @const */ var DIR_UP = new ascii.Vector(0, -1); /** @const */ var DIR_UP = new ascii.Vector(0, -1);
/** @const */ var DIR_DOWN = new ascii.Vector(0, 1); /** @const */ var DIR_DOWN = new ascii.Vector(0, 1);
/** @const */ var DIRECTIONS = [ DIR_LEFT, DIR_RIGHT, DIR_UP, DIR_DOWN ]; /** @const */ var DIRECTIONS = [DIR_LEFT, DIR_RIGHT, DIR_UP, DIR_DOWN];
/** /**
* An individual cell within the diagram and it's current value. * An individual cell within the diagram and it's current value.
@ -166,18 +167,22 @@ ascii.CellContext.prototype.sum = function() {
* A pair of a vector and a string value. Used in history management. * A pair of a vector and a string value. Used in history management.
* @constructor * @constructor
* @struct * @struct
* @param {ascii.Vector} position
* @param {string} value
*/ */
ascii.MappedValue = function(position, value) { ascii.MappedValue = function(position, value) {
this.position = position; this.position = position;
this.value = value; this.value = value;
} };
/** /**
* A pair of a vector and a cell. Used in history management. * A pair of a vector and a cell. Used in history management.
* @constructor * @constructor
* @struct * @struct
* @param {ascii.Vector} position
* @param {ascii.Cell} cell
*/ */
ascii.MappedCell = function(position, cell) { ascii.MappedCell = function(position, cell) {
this.position = position; this.position = position;
this.cell = cell; this.cell = cell;
} };

View File

@ -3,10 +3,10 @@
* @const * @const
*/ */
var Mode = { var Mode = {
NONE : 0, NONE: 0,
DRAG : 1, DRAG: 1,
DRAW : 2 DRAW: 2
} };
/** /**
* Handles user input events and modifies state. * Handles user input events and modifies state.
@ -35,7 +35,7 @@ ascii.Controller = function(view, state) {
ascii.Controller.prototype.startDraw = function(position) { ascii.Controller.prototype.startDraw = function(position) {
this.mode = Mode.DRAW; this.mode = Mode.DRAW;
this.drawFunction.start(this.view.screenToCell(position)); this.drawFunction.start(this.view.screenToCell(position));
} };
/** /**
* @param {ascii.Vector} position * @param {ascii.Vector} position
@ -44,7 +44,7 @@ ascii.Controller.prototype.startDrag = function(position) {
this.mode = Mode.DRAG; this.mode = Mode.DRAG;
this.dragOrigin = position; this.dragOrigin = position;
this.dragOriginCell = this.view.offset; this.dragOriginCell = this.view.offset;
} };
/** /**
* @param {ascii.Vector} position * @param {ascii.Vector} position
@ -77,6 +77,9 @@ ascii.Controller.prototype.handleMove = function(position) {
this.lastMoveCell = moveCell; this.lastMoveCell = moveCell;
}; };
/**
* Ends the current operation.
*/
ascii.Controller.prototype.endAll = function() { ascii.Controller.prototype.endAll = function() {
if (this.mode = Mode.DRAW) { if (this.mode = Mode.DRAW) {
this.drawFunction.end(); this.drawFunction.end();

View File

@ -57,7 +57,7 @@ ascii.DrawFunction.prototype.move = function(position) {};
ascii.DrawFunction.prototype.end = function() {}; ascii.DrawFunction.prototype.end = function() {};
/** Cursor for given cell. /** Cursor for given cell.
* @param {ascii.Vector} position * @param {ascii.Vector} position
* @return {string} * @return {string}
*/ */
ascii.DrawFunction.prototype.getCursor = function(position) {}; ascii.DrawFunction.prototype.getCursor = function(position) {};
/** Handle the key with given value being pressed. @param {string} value */ /** Handle the key with given value being pressed. @param {string} value */
@ -73,21 +73,30 @@ ascii.DrawBox = function(state) {
/** @type {ascii.Vector} */ this.startPosition = null; /** @type {ascii.Vector} */ this.startPosition = null;
}; };
/** @inheritDoc */
ascii.DrawBox.prototype.start = function(position) { ascii.DrawBox.prototype.start = function(position) {
this.startPosition = position; this.startPosition = position;
}; };
/** @inheritDoc */
ascii.DrawBox.prototype.move = function(position) { ascii.DrawBox.prototype.move = function(position) {
this.endPosition = position; this.endPosition = position;
this.state.clearDraw(); this.state.clearDraw();
drawLine(this.state, this.startPosition, position, true); drawLine(this.state, this.startPosition, position, true);
drawLine(this.state, this.startPosition, position, false); drawLine(this.state, this.startPosition, position, false);
}; };
/** @inheritDoc */
ascii.DrawBox.prototype.end = function() { ascii.DrawBox.prototype.end = function() {
this.state.commitDraw(); this.state.commitDraw();
}; };
/** @inheritDoc */
ascii.DrawBox.prototype.getCursor = function(position) { ascii.DrawBox.prototype.getCursor = function(position) {
return 'crosshair'; return 'crosshair';
}; };
/** @inheritDoc */
ascii.DrawBox.prototype.handleKey = function(value) {}; ascii.DrawBox.prototype.handleKey = function(value) {};
/** /**
@ -100,9 +109,12 @@ ascii.DrawLine = function(state) {
/** @type {ascii.Vector} */ this.startPosition = null; /** @type {ascii.Vector} */ this.startPosition = null;
}; };
/** @inheritDoc */
ascii.DrawLine.prototype.start = function(position) { ascii.DrawLine.prototype.start = function(position) {
this.startPosition = position; this.startPosition = position;
}; };
/** @inheritDoc */
ascii.DrawLine.prototype.move = function(position) { ascii.DrawLine.prototype.move = function(position) {
this.state.clearDraw(); this.state.clearDraw();
@ -115,12 +127,18 @@ ascii.DrawLine.prototype.move = function(position) {
drawLine(this.state, this.startPosition, position, clockwise); drawLine(this.state, this.startPosition, position, clockwise);
}; };
/** @inheritDoc */
ascii.DrawLine.prototype.end = function() { ascii.DrawLine.prototype.end = function() {
this.state.commitDraw(); this.state.commitDraw();
}; };
/** @inheritDoc */
ascii.DrawLine.prototype.getCursor = function(position) { ascii.DrawLine.prototype.getCursor = function(position) {
return 'crosshair'; return 'crosshair';
}; };
/** @inheritDoc */
ascii.DrawLine.prototype.handleKey = function(value) {}; ascii.DrawLine.prototype.handleKey = function(value) {};
/** /**
@ -134,18 +152,27 @@ ascii.DrawFreeform = function(state, value) {
this.value = value; this.value = value;
}; };
/** @inheritDoc */
ascii.DrawFreeform.prototype.start = function(position) { ascii.DrawFreeform.prototype.start = function(position) {
this.state.drawValue(position, this.value); this.state.drawValue(position, this.value);
}; };
/** @inheritDoc */
ascii.DrawFreeform.prototype.move = function(position) { ascii.DrawFreeform.prototype.move = function(position) {
this.state.drawValue(position, this.value); this.state.drawValue(position, this.value);
}; };
/** @inheritDoc */
ascii.DrawFreeform.prototype.end = function() { ascii.DrawFreeform.prototype.end = function() {
this.state.commitDraw(); this.state.commitDraw();
}; };
/** @inheritDoc */
ascii.DrawFreeform.prototype.getCursor = function(position) { ascii.DrawFreeform.prototype.getCursor = function(position) {
return 'crosshair'; return 'crosshair';
}; };
/** @inheritDoc */
ascii.DrawFreeform.prototype.handleKey = function(value) { ascii.DrawFreeform.prototype.handleKey = function(value) {
if (value.length == 1) { if (value.length == 1) {
// The value is not a special character, so lets use it. // The value is not a special character, so lets use it.
@ -164,6 +191,7 @@ ascii.DrawText = function(state) {
this.currentPosition = null; this.currentPosition = null;
}; };
/** @inheritDoc */
ascii.DrawText.prototype.start = function(position) { ascii.DrawText.prototype.start = function(position) {
this.startPosition = position; this.startPosition = position;
this.currentPosition = position; this.currentPosition = position;
@ -171,25 +199,34 @@ ascii.DrawText.prototype.start = function(position) {
this.state.clearDraw(); this.state.clearDraw();
// Effectively highlights the starting cell. // Effectively highlights the starting cell.
var currentValue = this.state.getCell(position).getRawValue(); var currentValue = this.state.getCell(position).getRawValue();
this.state.drawValue(position, currentValue == null ? ERASE_CHAR : currentValue); this.state.drawValue(position,
currentValue == null ? ERASE_CHAR : currentValue);
}; };
/** @inheritDoc */
ascii.DrawText.prototype.move = function(position) {}; ascii.DrawText.prototype.move = function(position) {};
/** @inheritDoc */
ascii.DrawText.prototype.end = function() {}; ascii.DrawText.prototype.end = function() {};
/** @inheritDoc */
ascii.DrawText.prototype.getCursor = function(position) { ascii.DrawText.prototype.getCursor = function(position) {
return 'text'; return 'text';
}; };
/** @inheritDoc */
ascii.DrawText.prototype.handleKey = function(value) { ascii.DrawText.prototype.handleKey = function(value) {
if (this.currentPosition == null) { if (this.currentPosition == null) {
return; return;
} }
var nextPosition = this.currentPosition.add(DIR_RIGHT); var nextPosition = this.currentPosition.add(DIR_RIGHT);
if (value == KEY_RETURN || this.state.getCell(nextPosition).isSpecial()) { if (value == KEY_RETURN || this.state.getCell(nextPosition).isSpecial()) {
// Pressed return key or hit box, so clear this cell and new line. // Pressed return key or hit box, so clear this cell and new line.
this.state.clearDraw(); this.state.clearDraw();
nextPosition = this.startPosition.add(DIR_DOWN); nextPosition = this.startPosition.add(DIR_DOWN);
this.startPosition = nextPosition; this.startPosition = nextPosition;
} }
if (value == KEY_BACKSPACE && this.startPosition.x <= nextPosition.x) { if (value == KEY_BACKSPACE && this.startPosition.x <= nextPosition.x) {
// Pressed backspace key, so clear this cell and go back. // Pressed backspace key, so clear this cell and go back.
this.state.clearDraw(); this.state.clearDraw();
@ -200,7 +237,7 @@ ascii.DrawText.prototype.handleKey = function(value) {
this.state.drawValue(nextPosition, ERASE_CHAR); this.state.drawValue(nextPosition, ERASE_CHAR);
this.state.commitDraw(); this.state.commitDraw();
} }
if (value == KEY_UP) { if (value == KEY_UP) {
this.state.clearDraw(); this.state.clearDraw();
this.startPosition = nextPosition = this.currentPosition.add(DIR_UP); this.startPosition = nextPosition = this.currentPosition.add(DIR_UP);
} }
@ -226,7 +263,8 @@ ascii.DrawText.prototype.handleKey = function(value) {
// Highlight the next cell. // Highlight the next cell.
this.currentPosition = nextPosition; this.currentPosition = nextPosition;
var nextValue = this.state.getCell(nextPosition).getRawValue(); var nextValue = this.state.getCell(nextPosition).getRawValue();
this.state.drawValue(nextPosition, nextValue == null ? ERASE_CHAR : nextValue); this.state.drawValue(nextPosition,
nextValue == null ? ERASE_CHAR : nextValue);
}; };
/** /**
@ -240,10 +278,13 @@ ascii.DrawErase = function(state) {
this.endPosition = null; this.endPosition = null;
}; };
/** @inheritDoc */
ascii.DrawErase.prototype.start = function(position) { ascii.DrawErase.prototype.start = function(position) {
this.startPosition = position; this.startPosition = position;
this.move(position); this.move(position);
}; };
/** @inheritDoc */
ascii.DrawErase.prototype.move = function(position) { ascii.DrawErase.prototype.move = function(position) {
this.state.clearDraw(); this.state.clearDraw();
this.endPosition = position; this.endPosition = position;
@ -259,12 +300,18 @@ ascii.DrawErase.prototype.move = function(position) {
} }
} }
}; };
/** @inheritDoc */
ascii.DrawErase.prototype.end = function() { ascii.DrawErase.prototype.end = function() {
this.state.commitDraw(); this.state.commitDraw();
}; };
/** @inheritDoc */
ascii.DrawErase.prototype.getCursor = function(position) { ascii.DrawErase.prototype.getCursor = function(position) {
return 'crosshair'; return 'crosshair';
}; };
/** @inheritDoc */
ascii.DrawErase.prototype.handleKey = function(value) {}; ascii.DrawErase.prototype.handleKey = function(value) {};
/** /**
@ -278,10 +325,10 @@ ascii.DrawMove = function(state) {
this.ends = null; this.ends = null;
}; };
/** @inheritDoc */
ascii.DrawMove.prototype.start = function(position) { ascii.DrawMove.prototype.start = function(position) {
this.startPosition = TOUCH_ENABLED this.startPosition =
? this.snapToNearest(position) TOUCH_ENABLED ? this.snapToNearest(position) : position;
: position;
this.ends = null; this.ends = null;
// If this isn't a special cell then quit, or things get weird. // If this isn't a special cell then quit, or things get weird.
@ -317,8 +364,10 @@ ascii.DrawMove.prototype.start = function(position) {
if (secondEnds.length == 0) { if (secondEnds.length == 0) {
continue; continue;
} }
// On the second line we don't care about multiple junctions, just the last. // On the second line we don't care about multiple
ends.push({position: secondEnds[secondEnds.length - 1], clockwise: clockwise}); // junctions, just the last.
ends.push({position: secondEnds[secondEnds.length - 1],
clockwise: clockwise});
} }
} }
} }
@ -327,6 +376,7 @@ ascii.DrawMove.prototype.start = function(position) {
this.move(this.startPosition); this.move(this.startPosition);
}; };
/** @inheritDoc */
ascii.DrawMove.prototype.move = function(position) { ascii.DrawMove.prototype.move = function(position) {
this.state.clearDraw(); this.state.clearDraw();
// Clear all the lines so we can draw them afresh. // Clear all the lines so we can draw them afresh.
@ -340,6 +390,7 @@ ascii.DrawMove.prototype.move = function(position) {
} }
}; };
/** @inheritDoc */
ascii.DrawMove.prototype.end = function() { ascii.DrawMove.prototype.end = function() {
this.state.commitDraw(); this.state.commitDraw();
}; };
@ -348,6 +399,9 @@ ascii.DrawMove.prototype.end = function() {
* Follows a line in a given direction from the startPosition. * Follows a line in a given direction from the startPosition.
* Returns a list of positions that were line 'junctions'. This is a bit of a * Returns a list of positions that were line 'junctions'. This is a bit of a
* loose definition, but basically means a point around which we resize things. * loose definition, but basically means a point around which we resize things.
* @param {ascii.Vector} startPosition
* @param {ascii.Vector} direction
* @return {Array.<ascii.Vector>}
*/ */
ascii.DrawMove.prototype.followLine = function(startPosition, direction) { ascii.DrawMove.prototype.followLine = function(startPosition, direction) {
var endPosition = startPosition.clone(); var endPosition = startPosition.clone();
@ -375,6 +429,7 @@ ascii.DrawMove.prototype.followLine = function(startPosition, direction) {
* For a given position, finds the nearest cell that is of any interest to the * For a given position, finds the nearest cell that is of any interest to the
* move tool, e.g. a corner or a line. Will look up to 1 cell in each direction * move tool, e.g. a corner or a line. Will look up to 1 cell in each direction
* including diagonally. * including diagonally.
* @param {ascii.Vector} position
* @return {ascii.Vector} * @return {ascii.Vector}
*/ */
ascii.DrawMove.prototype.snapToNearest = function(position) { ascii.DrawMove.prototype.snapToNearest = function(position) {
@ -393,8 +448,8 @@ ascii.DrawMove.prototype.snapToNearest = function(position) {
// Find the most connected cell, essentially. // Find the most connected cell, essentially.
var newPos = position.add(allDirections[i]); var newPos = position.add(allDirections[i]);
var contextSum = this.state.getContext(newPos).sum(); var contextSum = this.state.getContext(newPos).sum();
if (this.state.getCell(newPos).isSpecial() if (this.state.getCell(newPos).isSpecial() &&
&& contextSum > bestContextSum) { contextSum > bestContextSum) {
bestDirection = allDirections[i]; bestDirection = allDirections[i];
bestContextSum = contextSum; bestContextSum = contextSum;
} }
@ -404,8 +459,9 @@ ascii.DrawMove.prototype.snapToNearest = function(position) {
return position; return position;
} }
return position.add(bestDirection); return position.add(bestDirection);
} };
/** @inheritDoc */
ascii.DrawMove.prototype.getCursor = function(position) { ascii.DrawMove.prototype.getCursor = function(position) {
if (this.state.getCell(position).isSpecial()) { if (this.state.getCell(position).isSpecial()) {
return 'pointer'; return 'pointer';
@ -414,5 +470,6 @@ ascii.DrawMove.prototype.getCursor = function(position) {
} }
}; };
/** @inheritDoc */
ascii.DrawMove.prototype.handleKey = function(value) {}; ascii.DrawMove.prototype.handleKey = function(value) {};

View File

@ -9,20 +9,11 @@ ascii.DesktopController = function(controller) {
/** @type {boolean} */ this.isDragging = false; /** @type {boolean} */ this.isDragging = false;
this.installBindings(); this.installBindings();
}
/**
* @param {ascii.Vector} position
*/
ascii.DesktopController.prototype.handlePress = function(position, e) {
// Can drag by holding either the control or meta (Apple) key.
if (e.ctrlKey || e.metaKey) {
this.controller.startDrag(position);
} else {
this.controller.startDraw(position);
}
}; };
/**
* Installs input bindings associated with keyboard controls.
*/
ascii.DesktopController.prototype.installBindings = function() { ascii.DesktopController.prototype.installBindings = function() {
var canvas = this.controller.view.canvas; var canvas = this.controller.view.canvas;
$(canvas).bind('mousewheel', function(e) { $(canvas).bind('mousewheel', function(e) {
@ -30,7 +21,12 @@ ascii.DesktopController.prototype.installBindings = function() {
}.bind(this)); }.bind(this));
$(canvas).mousedown(function(e) { $(canvas).mousedown(function(e) {
this.handlePress(new ascii.Vector(e.clientX, e.clientY), e); // Can drag by holding either the control or meta (Apple) key.
if (e.ctrlKey || e.metaKey) {
this.controller.startDrag(new ascii.Vector(e.clientX, e.clientY));
} else {
this.controller.startDraw(new ascii.Vector(e.clientX, e.clientY));
}
}.bind(this)); }.bind(this));
// Pass these events through to the main controller. // Pass these events through to the main controller.
@ -61,7 +57,7 @@ ascii.TouchController = function(controller) {
/** @type {boolean} */ this.dragStarted = false; /** @type {boolean} */ this.dragStarted = false;
this.installBindings(); this.installBindings();
} };
/** /**
* @param {ascii.Vector} position * @param {ascii.Vector} position
@ -94,6 +90,9 @@ ascii.TouchController.prototype.handleMove = function(position) {
this.controller.handleMove(position); this.controller.handleMove(position);
}; };
/**
* Installs input bindings associated with touch controls.
*/
ascii.TouchController.prototype.installBindings = function() { ascii.TouchController.prototype.installBindings = function() {
var canvas = this.controller.view.canvas; var canvas = this.controller.view.canvas;

View File

@ -30,7 +30,7 @@ ascii.State.prototype.clear = function() {
for (var i = 0; i < this.cells.length; i++) { for (var i = 0; i < this.cells.length; i++) {
for (var j = 0; j < this.cells[i].length; j++) { for (var j = 0; j < this.cells[i].length; j++) {
var position = new ascii.Vector(i, j); var position = new ascii.Vector(i, j);
if(this.cells[i][j].getRawValue() != null) { if (this.cells[i][j].getRawValue() != null) {
this.drawValue(new ascii.Vector(i, j), ERASE_CHAR); this.drawValue(new ascii.Vector(i, j), ERASE_CHAR);
} }
} }
@ -132,10 +132,11 @@ ascii.State.prototype.commitDraw = function(opt_skipSave) {
var oldValues = []; var oldValues = [];
// Dedupe the scratch values, or this causes havoc for history management. // Dedupe the scratch values, or this causes havoc for history management.
var positions = this.scratchCells.map(function (value) { var positions = this.scratchCells.map(function(value) {
return value.position.x.toString() + value.position.y.toString(); return value.position.x.toString() + value.position.y.toString();
}); });
var scratchCellsUnique = this.scratchCells.filter(function (value, index, arr) { var scratchCellsUnique =
this.scratchCells.filter(function(value, index, arr) {
return positions.indexOf(positions[index]) == index; return positions.indexOf(positions[index]) == index;
}); });
@ -146,7 +147,8 @@ ascii.State.prototype.commitDraw = function(opt_skipSave) {
var cell = scratchCellsUnique[i].cell; var cell = scratchCellsUnique[i].cell;
// Push the effective old value unto the array. // Push the effective old value unto the array.
oldValues.push(new ascii.MappedValue(position, cell.value != null ? cell.value : ' ')); oldValues.push(new ascii.MappedValue(position,
cell.value != null ? cell.value : ' '));
var newValue = cell.getRawValue(); var newValue = cell.getRawValue();
if (newValue == ERASE_CHAR || newValue == ' ') { if (newValue == ERASE_CHAR || newValue == ' ') {
@ -159,7 +161,7 @@ ascii.State.prototype.commitDraw = function(opt_skipSave) {
// Don't save a new state if we are undoing an old one. // Don't save a new state if we are undoing an old one.
if (!opt_skipSave && oldValues.length > 0) { if (!opt_skipSave && oldValues.length > 0) {
// If we have too many undo states, clear one out. // If we have too many undo states, clear one out.
if(this.undoStates.length > MAX_UNDO) { if (this.undoStates.length > MAX_UNDO) {
this.undoStates.shift(); this.undoStates.shift();
} }
this.undoStates.push(oldValues); this.undoStates.push(oldValues);
@ -190,7 +192,7 @@ ascii.State.prototype.outputText = function() {
var start = new ascii.Vector(Number.MAX_VALUE, Number.MAX_VALUE); var start = new ascii.Vector(Number.MAX_VALUE, Number.MAX_VALUE);
var end = new ascii.Vector(-1, -1); var end = new ascii.Vector(-1, -1);
for (var i = 0; i < this.cells.length; i++) { for (var i = 0; i < this.cells.length; i++) {
for (var j = 0; j < this.cells[i].length; j++) { for (var j = 0; j < this.cells[i].length; j++) {
if (this.cells[i][j].getRawValue() != null) { if (this.cells[i][j].getRawValue() != null) {
if (i < start.x) { start.x = i; } if (i < start.x) { start.x = i; }
@ -200,7 +202,7 @@ ascii.State.prototype.outputText = function() {
} }
} }
} }
if (end.x < 0) { return '' }; if (end.x < 0) { return '' }
var output = ''; var output = '';
for (var j = start.y; j <= end.y; j++) { for (var j = start.y; j <= end.y; j++) {
@ -217,6 +219,8 @@ ascii.State.prototype.outputText = function() {
/** /**
* Loads the given text into the diagram starting at the given offset. * Loads the given text into the diagram starting at the given offset.
* @param {string} value
* @param {ascii.Vector} offset
*/ */
ascii.State.prototype.fromText = function(value, offset) { ascii.State.prototype.fromText = function(value, offset) {
var lines = value.split('\n'); var lines = value.split('\n');

View File

@ -91,8 +91,10 @@ ascii.View.prototype.render = function() {
for (var i = startOffset.x; i < endOffset.x; i++) { for (var i = startOffset.x; i < endOffset.x; i++) {
for (var j = startOffset.y; j < endOffset.y; j++) { for (var j = startOffset.y; j < endOffset.y; j++) {
var cell = this.state.getCell(new ascii.Vector(i, j)); var cell = this.state.getCell(new ascii.Vector(i, j));
// Highlight the cell if it is special (grey) or it is part of a visible edit (blue). // Highlight the cell if it is special (grey) or it is part
if (cell.isSpecial() || (cell.hasScratch() && cell.getRawValue() != ' ')) { // of a visible edit (blue).
if (cell.isSpecial() ||
(cell.hasScratch() && cell.getRawValue() != ' ')) {
this.context.fillStyle = cell.hasScratch() ? '#DEF' : '#F5F5F5'; this.context.fillStyle = cell.hasScratch() ? '#DEF' : '#F5F5F5';
context.fillRect( context.fillRect(
i * CHAR_PIXELS_H - this.offset.x, i * CHAR_PIXELS_H - this.offset.x,
@ -156,8 +158,12 @@ ascii.View.prototype.frameToScreen = function(vector) {
ascii.View.prototype.frameToCell = function(vector) { ascii.View.prototype.frameToCell = function(vector) {
// We limit the edges in a bit, as most drawing needs a full context to work. // We limit the edges in a bit, as most drawing needs a full context to work.
return new ascii.Vector( return new ascii.Vector(
Math.min(Math.max(1, Math.round((vector.x - CHAR_PIXELS_H / 2) / CHAR_PIXELS_H)), MAX_GRID_WIDTH - 2), Math.min(Math.max(1,
Math.min(Math.max(1, Math.round((vector.y + CHAR_PIXELS_V / 2) / CHAR_PIXELS_V)), MAX_GRID_HEIGHT - 2)); Math.round((vector.x - CHAR_PIXELS_H / 2) / CHAR_PIXELS_H)),
MAX_GRID_WIDTH - 2),
Math.min(Math.max(1,
Math.round((vector.y + CHAR_PIXELS_V / 2) / CHAR_PIXELS_V)),
MAX_GRID_HEIGHT - 2));
}; };
/** /**