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');
throw 1;
} catch (e) {
/** type {Object} */
window.ascii = window.ascii || {};
}
@ -41,7 +42,7 @@ try {
/** @const */ var KEY_RIGHT = '<right>';
// 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 ||
'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_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.
@ -166,18 +167,22 @@ ascii.CellContext.prototype.sum = function() {
* A pair of a vector and a string value. Used in history management.
* @constructor
* @struct
* @param {ascii.Vector} position
* @param {string} value
*/
ascii.MappedValue = function(position, value) {
this.position = position;
this.value = value;
}
};
/**
* A pair of a vector and a cell. Used in history management.
* @constructor
* @struct
* @param {ascii.Vector} position
* @param {ascii.Cell} cell
*/
ascii.MappedCell = function(position, cell) {
this.position = position;
this.cell = cell;
}
};

View File

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

View File

@ -57,7 +57,7 @@ ascii.DrawFunction.prototype.move = function(position) {};
ascii.DrawFunction.prototype.end = function() {};
/** Cursor for given cell.
* @param {ascii.Vector} position
* @return {string}
* @return {string}
*/
ascii.DrawFunction.prototype.getCursor = function(position) {};
/** 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;
};
/** @inheritDoc */
ascii.DrawBox.prototype.start = function(position) {
this.startPosition = position;
};
/** @inheritDoc */
ascii.DrawBox.prototype.move = function(position) {
this.endPosition = position;
this.state.clearDraw();
drawLine(this.state, this.startPosition, position, true);
drawLine(this.state, this.startPosition, position, false);
};
/** @inheritDoc */
ascii.DrawBox.prototype.end = function() {
this.state.commitDraw();
};
/** @inheritDoc */
ascii.DrawBox.prototype.getCursor = function(position) {
return 'crosshair';
};
/** @inheritDoc */
ascii.DrawBox.prototype.handleKey = function(value) {};
/**
@ -100,9 +109,12 @@ ascii.DrawLine = function(state) {
/** @type {ascii.Vector} */ this.startPosition = null;
};
/** @inheritDoc */
ascii.DrawLine.prototype.start = function(position) {
this.startPosition = position;
};
/** @inheritDoc */
ascii.DrawLine.prototype.move = function(position) {
this.state.clearDraw();
@ -115,12 +127,18 @@ ascii.DrawLine.prototype.move = function(position) {
drawLine(this.state, this.startPosition, position, clockwise);
};
/** @inheritDoc */
ascii.DrawLine.prototype.end = function() {
this.state.commitDraw();
};
/** @inheritDoc */
ascii.DrawLine.prototype.getCursor = function(position) {
return 'crosshair';
};
/** @inheritDoc */
ascii.DrawLine.prototype.handleKey = function(value) {};
/**
@ -134,18 +152,27 @@ ascii.DrawFreeform = function(state, value) {
this.value = value;
};
/** @inheritDoc */
ascii.DrawFreeform.prototype.start = function(position) {
this.state.drawValue(position, this.value);
};
/** @inheritDoc */
ascii.DrawFreeform.prototype.move = function(position) {
this.state.drawValue(position, this.value);
};
/** @inheritDoc */
ascii.DrawFreeform.prototype.end = function() {
this.state.commitDraw();
};
/** @inheritDoc */
ascii.DrawFreeform.prototype.getCursor = function(position) {
return 'crosshair';
};
/** @inheritDoc */
ascii.DrawFreeform.prototype.handleKey = function(value) {
if (value.length == 1) {
// The value is not a special character, so lets use it.
@ -164,6 +191,7 @@ ascii.DrawText = function(state) {
this.currentPosition = null;
};
/** @inheritDoc */
ascii.DrawText.prototype.start = function(position) {
this.startPosition = position;
this.currentPosition = position;
@ -171,25 +199,34 @@ ascii.DrawText.prototype.start = function(position) {
this.state.clearDraw();
// Effectively highlights the starting cell.
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) {};
/** @inheritDoc */
ascii.DrawText.prototype.end = function() {};
/** @inheritDoc */
ascii.DrawText.prototype.getCursor = function(position) {
return 'text';
};
/** @inheritDoc */
ascii.DrawText.prototype.handleKey = function(value) {
if (this.currentPosition == null) {
return;
}
var nextPosition = this.currentPosition.add(DIR_RIGHT);
if (value == KEY_RETURN || this.state.getCell(nextPosition).isSpecial()) {
// Pressed return key or hit box, so clear this cell and new line.
this.state.clearDraw();
nextPosition = this.startPosition.add(DIR_DOWN);
this.startPosition = nextPosition;
}
}
if (value == KEY_BACKSPACE && this.startPosition.x <= nextPosition.x) {
// Pressed backspace key, so clear this cell and go back.
this.state.clearDraw();
@ -200,7 +237,7 @@ ascii.DrawText.prototype.handleKey = function(value) {
this.state.drawValue(nextPosition, ERASE_CHAR);
this.state.commitDraw();
}
if (value == KEY_UP) {
if (value == KEY_UP) {
this.state.clearDraw();
this.startPosition = nextPosition = this.currentPosition.add(DIR_UP);
}
@ -226,7 +263,8 @@ ascii.DrawText.prototype.handleKey = function(value) {
// Highlight the next cell.
this.currentPosition = nextPosition;
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;
};
/** @inheritDoc */
ascii.DrawErase.prototype.start = function(position) {
this.startPosition = position;
this.move(position);
};
/** @inheritDoc */
ascii.DrawErase.prototype.move = function(position) {
this.state.clearDraw();
this.endPosition = position;
@ -259,12 +300,18 @@ ascii.DrawErase.prototype.move = function(position) {
}
}
};
/** @inheritDoc */
ascii.DrawErase.prototype.end = function() {
this.state.commitDraw();
};
/** @inheritDoc */
ascii.DrawErase.prototype.getCursor = function(position) {
return 'crosshair';
};
/** @inheritDoc */
ascii.DrawErase.prototype.handleKey = function(value) {};
/**
@ -278,10 +325,10 @@ ascii.DrawMove = function(state) {
this.ends = null;
};
/** @inheritDoc */
ascii.DrawMove.prototype.start = function(position) {
this.startPosition = TOUCH_ENABLED
? this.snapToNearest(position)
: position;
this.startPosition =
TOUCH_ENABLED ? this.snapToNearest(position) : position;
this.ends = null;
// 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) {
continue;
}
// On the second line we don't care about multiple junctions, just the last.
ends.push({position: secondEnds[secondEnds.length - 1], clockwise: clockwise});
// On the second line we don't care about multiple
// 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);
};
/** @inheritDoc */
ascii.DrawMove.prototype.move = function(position) {
this.state.clearDraw();
// 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() {
this.state.commitDraw();
};
@ -348,6 +399,9 @@ ascii.DrawMove.prototype.end = function() {
* 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
* 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) {
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
* move tool, e.g. a corner or a line. Will look up to 1 cell in each direction
* including diagonally.
* @param {ascii.Vector} position
* @return {ascii.Vector}
*/
ascii.DrawMove.prototype.snapToNearest = function(position) {
@ -393,8 +448,8 @@ ascii.DrawMove.prototype.snapToNearest = function(position) {
// Find the most connected cell, essentially.
var newPos = position.add(allDirections[i]);
var contextSum = this.state.getContext(newPos).sum();
if (this.state.getCell(newPos).isSpecial()
&& contextSum > bestContextSum) {
if (this.state.getCell(newPos).isSpecial() &&
contextSum > bestContextSum) {
bestDirection = allDirections[i];
bestContextSum = contextSum;
}
@ -404,8 +459,9 @@ ascii.DrawMove.prototype.snapToNearest = function(position) {
return position;
}
return position.add(bestDirection);
}
};
/** @inheritDoc */
ascii.DrawMove.prototype.getCursor = function(position) {
if (this.state.getCell(position).isSpecial()) {
return 'pointer';
@ -414,5 +470,6 @@ ascii.DrawMove.prototype.getCursor = function(position) {
}
};
/** @inheritDoc */
ascii.DrawMove.prototype.handleKey = function(value) {};

View File

@ -9,20 +9,11 @@ ascii.DesktopController = function(controller) {
/** @type {boolean} */ this.isDragging = false;
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() {
var canvas = this.controller.view.canvas;
$(canvas).bind('mousewheel', function(e) {
@ -30,7 +21,12 @@ ascii.DesktopController.prototype.installBindings = function() {
}.bind(this));
$(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));
// Pass these events through to the main controller.
@ -61,7 +57,7 @@ ascii.TouchController = function(controller) {
/** @type {boolean} */ this.dragStarted = false;
this.installBindings();
}
};
/**
* @param {ascii.Vector} position
@ -94,6 +90,9 @@ ascii.TouchController.prototype.handleMove = function(position) {
this.controller.handleMove(position);
};
/**
* Installs input bindings associated with touch controls.
*/
ascii.TouchController.prototype.installBindings = function() {
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 j = 0; j < this.cells[i].length; 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);
}
}
@ -132,10 +132,11 @@ ascii.State.prototype.commitDraw = function(opt_skipSave) {
var oldValues = [];
// 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();
});
var scratchCellsUnique = this.scratchCells.filter(function (value, index, arr) {
var scratchCellsUnique =
this.scratchCells.filter(function(value, index, arr) {
return positions.indexOf(positions[index]) == index;
});
@ -146,7 +147,8 @@ ascii.State.prototype.commitDraw = function(opt_skipSave) {
var cell = scratchCellsUnique[i].cell;
// 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();
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.
if (!opt_skipSave && oldValues.length > 0) {
// 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.push(oldValues);
@ -190,7 +192,7 @@ ascii.State.prototype.outputText = function() {
var start = new ascii.Vector(Number.MAX_VALUE, Number.MAX_VALUE);
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++) {
if (this.cells[i][j].getRawValue() != null) {
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 = '';
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.
* @param {string} value
* @param {ascii.Vector} offset
*/
ascii.State.prototype.fromText = function(value, offset) {
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 j = startOffset.y; j < endOffset.y; 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).
if (cell.isSpecial() || (cell.hasScratch() && cell.getRawValue() != ' ')) {
// Highlight the cell if it is special (grey) or it is part
// of a visible edit (blue).
if (cell.isSpecial() ||
(cell.hasScratch() && cell.getRawValue() != ' ')) {
this.context.fillStyle = cell.hasScratch() ? '#DEF' : '#F5F5F5';
context.fillRect(
i * CHAR_PIXELS_H - this.offset.x,
@ -156,8 +158,12 @@ ascii.View.prototype.frameToScreen = function(vector) {
ascii.View.prototype.frameToCell = function(vector) {
// We limit the edges in a bit, as most drawing needs a full context to work.
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.round((vector.y + CHAR_PIXELS_V / 2) / CHAR_PIXELS_V)), MAX_GRID_HEIGHT - 2));
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.round((vector.y + CHAR_PIXELS_V / 2) / CHAR_PIXELS_V)),
MAX_GRID_HEIGHT - 2));
};
/**