Update tests, coding spec, and more.

Rewrite Entities and object creators.
This commit is contained in:
Tom MacWright
2012-10-25 19:34:26 -04:00
parent 6fb8df09ea
commit f19e5196b3
7 changed files with 57 additions and 84 deletions

View File

@@ -1,22 +1,12 @@
Coding standards and advice for iD
==================================
Classes
Objects
-------
All constructors must initialise objects and arrays. It is not enough to say
array:[],
constructor:function() {
},
but rather, you should do
array: null, // effectively a placeholder
constructor:function() {
this.array=[],
},
or bad things will happen. You should still declare the object outside the constructor, but for clarity rather than functionality.
(This doesn't apply to simple types - numbers, strings, booleans - which you can declare as normal.)
Most of iD is written with [a js module pattern](http://macwright.org/2012/06/04/the-module-pattern.html):
that is, they do not use the `new` operator, and they use scope instead of
`this` to reference variables and functions.
Function names
--------------
@@ -30,14 +20,10 @@ and commented as such. Underscores are also used to prefix private methods.
File naming
-----------
The filename should be the name of the base class. You can add subclasses within that file for clarity. Don't add extra classes that aren't subclasses, unless they're not referenced from elsewhere.
The filename should be the name of the base class. You can add subclasses within
that file for clarity. Don't add extra classes that aren't subclasses,
unless they're not referenced from elsewhere.
Layout
------
* Hard tabs, indent of 4.
* Do not indent the root level of the module. Add an 'End of module' comment instead.
Useful stuff to know about Dojo
-------------------------------
* The array and lang modules are full of useful add-ons to basic JavaScript functionality. lang/hitch will save your life with scopes.
* Soft tabs

View File

@@ -34,12 +34,13 @@
<script type="text/javascript" src="js/iD/Way.js"></script>
<script type="text/javascript" src="js/iD/Connection.js"></script>
<script type="text/javascript" src="js/iD/Controller.js"></script>
<script type="text/javascript" src="js/iD/controller/DrawWay.js"></script>
<div id='modebuttons'>
<button id='add-place'>
+ Place</button><!-- <button id="add-road">
+ Place</button><button id="add-road">
+ Road</button><button id="add-area">
+ Area</button>--><button class='mini' id="undo">
+ Area</button><button class='mini' id="undo">
&larr;</button><button class='mini' id="redo">
&rarr;</button><form action='GET' id='geocode-form'><input type='text' id='geocode-location' placeholder='find a place' />
</form>
@@ -73,7 +74,7 @@
// ----------------------------------------------------
// Data is loaded and app ready to go
// Set initial controllerState
map.controller.setState(new iD.controller.edit.NoSelection());
// map.controller.setState(iD.DrawWay());
// ----------------------------------------------------
// Mode button handlers
@@ -82,7 +83,9 @@
});
d3.select('#add-road').on('click', function() {
map.controller.setState(new iD.controller.shape.NoSelection('way'));
// map.controller.setState(new iD.controller.shape.DrawWay('way'));
console.log(iD.DrawWay.enter());
console.log(iD.DrawWay.enter(map));
});
d3.select('#add-area').on('click', function() {
@@ -106,6 +109,7 @@
});
});
/*
$('#undo').click(function() {
map.controller.undoStack.undo();
map.updateUIs(true, true);
@@ -126,6 +130,7 @@
$('#zoomOut').click(function() {
map.zoomOut();
});
*/
</script>
</body>
</html>

View File

@@ -76,12 +76,10 @@ iD.Connection = function(apiURL) {
});
}
// ----------
// OSM parser
function loadFromAPI(box, callback) {
// summary: Request data within the bbox from an external OSM server. Currently hardcoded
// to use Overpass API (which has the relevant CORS headers).
loadFromURL("http://www.overpass-api.de/api/xapi?map?bbox=" +
loadFromURL('http://www.overpass-api.de/api/xapi?map?bbox=' +
[box[0][0], box[1][1], box[1][0], box[0][1]], callback);
}

View File

@@ -1,69 +1,53 @@
if (typeof iD === 'undefined') iD = {};
iD.Entity = function() {
this.parents = {};
// The ID locally
this._id = iD.Util.id();
this.connection = null;
var entity = {};
// The ID in OSM terms
this.id = NaN;
this.loaded = false;
this.entityType = '';
this.modified = false;
this.deleted = false;
};
iD.Entity.prototype = {
toString:function() {
return this.entityType + " . " + this.id;
},
// Provoke redraw and other changes
refresh:function() {
// summary: Ask the connection to provoke redraw and other changes.
this.connection.refreshEntity(this);
},
// Bounding box check (to be overridden)
within:function(left, right, top, bottom) {
// summary: Is the entity within the specified bbox?
return !this.deleted; // Boolean
},
entity.parents = {};
entity.connection = null;
entity._id = iD.Util.id();
entity.id = NaN;
entity.loaded = false;
entity.entityType = '';
entity.modified = false;
entity.deleted = false;
// Parent-handling
addParent: function(entity) {
entity.addParent = function(x) {
// summary: Record a parent (a relation or way which contains this entity).
this.parents[entity._id] = entity;
},
removeParent: function(entity) {
entity.parents[x._id] = x;
};
entity.removeParent = function(x) {
// summary: Remove a parent (e.g. when node removed from a way).
delete this.parents[entity._id];
},
hasParent: function(entity) {
delete entity.parents[x._id];
};
entity.hasParent = function(x) {
// summary: Does this entity have the specified parent (e.g. is it in a certain relation)?
return !!this.parents[entity._id];
},
parentObjects: function() {
return !!entity.parents[x._id];
};
entity.parentObjects = function() {
// summary: List of all parents of this entity.
return _.values(this.parents);
},
hasParentWays: function() {
return _.values(entity.parents);
};
entity.hasParentWays = function() {
// summary: Does this entity have any parents which are ways?
return !!_.find(this.parentObjects(), function(p) {
return !!_.find(entity.parentObjects(), function(p) {
return p.entityType === 'way';
});
},
parentWays: function() {
// summary: Return an array of all ways that this entity is a member of.
return this._parentObjectsOfClass('way'); // Array
},
parentRelations: function() {
// summary: Return an array of all relations that this entity is a member of.
return this._parentObjectsOfClass('relation'); // Array
},
_parentObjectsOfClass: function(_class) {
return _.filter(this.parentObjects(), function(p) {
};
entity.parentWays = function() {
return entity._parentObjectsOfClass('way');
};
entity.parentRelations = function() {
return entity._parentObjectsOfClass('relation');
};
function _parentObjectsOfClass(_class) {
return _.filter(entity.parentObjects(), function(p) {
return p.entityType === _class;
});
}
return entity;
};

View File

@@ -6,7 +6,7 @@ iD.Node = function(connection, id, lat, lon, tags, loaded) {
this.connection = connection;
this.id = id;
this._id = iD.Util.id();
this.entity = new iD.Entity();
this.entity = iD.Entity();
this.lat = lat;
this.lon = lon;
// TODO: keep or trash this custom

View File

@@ -7,7 +7,7 @@ iD.Way = function(connection, id, nodes, tags, loaded) {
this.id = id;
this._id = iD.Util.id();
this.deleted = false;
this.entity = new iD.Entity();
this.entity = iD.Entity();
this.tags = tags || {};
this.loaded = (loaded === undefined) ? true : loaded;
this.modified = this.id < 0;

View File

@@ -2,7 +2,7 @@ describe('Entity', function() {
var entity;
beforeEach(function() {
entity = new iD.Entity();
entity = iD.Entity();
});
it('has no entity type', function() {