diff --git a/NOTES.md b/NOTES.md index 29d49ba7f..58ceda05b 100644 --- a/NOTES.md +++ b/NOTES.md @@ -1,3 +1,17 @@ +## Code Layout + +This follows a similar layout to d3: each module of d3 has a file with its exact +name, like + +```javascript +// format.js + +iD.format = {}; +``` + +And the parts of that module are in separate files that implement `iD.format.XML` +and so on. + ## The Graph iD implements a [persistent data structure](http://en.wikipedia.org/wiki/Persistent_data_structure) diff --git a/index.html b/index.html index e83b5cb60..08e755cf2 100755 --- a/index.html +++ b/index.html @@ -47,8 +47,10 @@ + + diff --git a/js/iD/Connection.js b/js/iD/Connection.js index a37be63b0..30de3c9ab 100755 --- a/js/iD/Connection.js +++ b/js/iD/Connection.js @@ -27,6 +27,7 @@ iD.Connection = function(graph) { } // + // { highway: 'classified' } function getTags(obj) { var tags = {}, tagelems = obj.getElementsByTagName('tag'); for (var i = 0, l = tagelems.length; i < l; i++) { diff --git a/js/iD/actions/actions.js b/js/iD/actions/actions.js index 7deed4ce3..8cd2f09ef 100644 --- a/js/iD/actions/actions.js +++ b/js/iD/actions/actions.js @@ -1,5 +1,11 @@ iD.actions = {}; +// Actions are like 'modes' for the editor. They are entered by bindings to +// clicks and keypresses, and exited by the same. +// +// Actions aim to include a bare minimum of 'business logic' - this is separated +// into operations. + iD.actions._node = function(ll) { return { type: 'node', @@ -172,7 +178,8 @@ iD.actions.Move = { exit: function() { } }; - +// A controller holds a single action at a time and calls `.enter` and `.exit` +// to bind and unbind actions. iD.controller = function(map) { var controller = { action: null }; diff --git a/js/iD/actions/operations.js b/js/iD/actions/operations.js index 4653db994..39216d52e 100644 --- a/js/iD/actions/operations.js +++ b/js/iD/actions/operations.js @@ -1,5 +1,9 @@ iD.operations = {}; +// operations take a map, and arguments that they modify in the map's graph. +// they use `graph.modify` to do this while keeping a previous version +// of the graph the same. + iD.operations.addNode = function(map, node) { map.graph.modify(function(graph) { var o = {}; @@ -20,7 +24,6 @@ iD.operations.startWay = function(map, way) { iD.operations.remove = function(map, node) { map.graph.modify(function(graph) { - console.log(node.id); return graph.remove(node.id); }, 'removed a feature'); map.update(); diff --git a/js/iD/format/GeoJSON.js b/js/iD/format/GeoJSON.js index 08f9257fd..5821fb550 100644 --- a/js/iD/format/GeoJSON.js +++ b/js/iD/format/GeoJSON.js @@ -1,4 +1,4 @@ -iD.GeoJSON = { +iD.format.GeoJSON = { mapping: function(entity) { if (this.mappings[entity.type]) { return this.mappings[entity.type](entity); diff --git a/js/iD/format/XML.js b/js/iD/format/XML.js index 8fd3e179a..24e3938b8 100644 --- a/js/iD/format/XML.js +++ b/js/iD/format/XML.js @@ -1,4 +1,4 @@ -iD.XML = { +iD.format.XML = { mapping: function(entity) { if (this.mappings[entity.type]) { return this.mappings[entity.type](entity); diff --git a/js/iD/graph/Graph.js b/js/iD/graph/Graph.js index 54dada92b..4797689ea 100644 --- a/js/iD/graph/Graph.js +++ b/js/iD/graph/Graph.js @@ -30,9 +30,11 @@ iD.Graph.prototype = { return pois; }, + // rewind and fast-forward the graph. these preserve the other modes of the + // graph. these attempt to skip over any edits that didn't have an annotation, + // like 'invisible edits' and sub-edits. undo: function() { if (this.prev.length && this.prev[0] !== this.head) { - // skip changes without annotations for (var idx = this.prev.indexOf(this.head) - 1; idx > 0; idx--) { if (this.annotations[idx]) break; } @@ -40,7 +42,6 @@ iD.Graph.prototype = { this.annotation = this.annotations[idx]; } }, - redo: function() { if (this.prev.length && this.prev[this.prev.length - 1] !== this.head) { for (var idx = this.prev.indexOf(this.head) + 1; idx < this.prev.length - 1; idx++) { @@ -58,6 +59,11 @@ iD.Graph.prototype = { } }, + // the gist of all operations on the graph: the callback function + // receives the current graph and returns a modified graph. the graph + // given to the callback is guaranteed to be immutable at one level - the + // key -> object mappings. the callback is responsible for keeping objects + // in the graph immutable. modify: function(callback, annotation) { // create a pdata wrapper of current head var o = pdata.object(this.head); @@ -79,6 +85,7 @@ iD.Graph.prototype = { this.annotation = this.annotations[this.annotations.length - 1]; }, + // get all objects that intersect an extent. intersects: function(extent) { var items = []; for (var i in this.head) { diff --git a/js/iD/renderer/markers.js b/js/iD/renderer/markers.js index 15c31220c..c40cb3407 100644 --- a/js/iD/renderer/markers.js +++ b/js/iD/renderer/markers.js @@ -1,5 +1,6 @@ +// an index of tag -> marker image combinations, taken from +// http://svn.openstreetmap.org/applications/rendering/mapnik/inc/layer-amenity-symbols.xml.inc iD._markers = [ - // http://svn.openstreetmap.org/applications/rendering/mapnik/inc/layer-amenity-symbols.xml.inc { tags: { aeroway: 'helipad' }, icon: 'helipad' @@ -548,6 +549,7 @@ iD._markers = [ } ]; +// generate a fast lookup table for marker styling iD._markertable = (function(markers) { var table = {}; for (var i = 0; i < markers.length; i++) { diff --git a/js/iD/renderer/style.js b/js/iD/renderer/style.js index 2bde188cf..1f2b0c9e2 100644 --- a/js/iD/renderer/style.js +++ b/js/iD/renderer/style.js @@ -1,4 +1,12 @@ iD.Style = {}; + +// all styling that is done outside of CSS in iD. +// +// Since SVG does not support z-index, we sort roads manually with d3's `sort` +// and the `waystack` fn. +// +// This also chooses kosher CSS classes for ways, and marker images for POIs + iD.Style.highway_stack = { motorway: 0, motorway_link: 1, diff --git a/js/iD/renderer/tiles.js b/js/iD/renderer/tiles.js index db4a71261..8161aeb45 100644 --- a/js/iD/renderer/tiles.js +++ b/js/iD/renderer/tiles.js @@ -2,6 +2,7 @@ iD.Tiles = function(selection, projection, width, height) { var tiles = {}; + // derive the url of a 'quadkey' style tile from a coordinate object function tileUrl(coord) { var u = ''; for (var zoom = coord[0]; zoom > 0; zoom--) { @@ -14,6 +15,8 @@ iD.Tiles = function(selection, projection, width, height) { return 'http://ecn.t0.tiles.virtualearth.net/tiles/a' + u + '.jpeg?g=587&mkt=en-gb&n=z'; } + // derive the tiles onscreen, remove those offscreen and position tiles + // correctly for the currentstate of `projection` function redraw() { var t = projection.translate(), s = projection.scale(), diff --git a/js/iD/ui/Inspector.js b/js/iD/ui/Inspector.js index dec278d12..3dfd8ccd2 100644 --- a/js/iD/ui/Inspector.js +++ b/js/iD/ui/Inspector.js @@ -26,7 +26,7 @@ iD.Inspector = function(graph) { .text('XML') .on('click', function() { d3.event.stopPropagation(); - iD.Util.codeWindow(iD.XML.mapping(graph.fetch(d.id))); + iD.Util.codeWindow(iD.format.XML.mapping(graph.fetch(d.id))); }); head.append('a') @@ -36,7 +36,7 @@ iD.Inspector = function(graph) { .on('click', function() { d3.event.stopPropagation(); iD.Util.codeWindow(JSON.stringify( - iD.GeoJSON.mapping(graph.fetch(d.id)), null, 2)); + iD.format.GeoJSON.mapping(graph.fetch(d.id)), null, 2)); }); var table = d3.select(this)