diff --git a/Makefile b/Makefile index c9d13ff60..ddeef62b9 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,8 @@ all: \ js/id/behavior/*.js \ js/id/modes.js \ js/id/modes/*.js \ + js/id/operations.js \ + js/id/operations/*.js \ js/id/controller/*.js \ js/id/graph/*.js \ js/id/renderer/*.js \ @@ -45,7 +47,9 @@ all: \ js/id/svg/*.js \ js/id/ui.js \ js/id/ui/*.js \ - js/id/end.js + js/id/end.js \ + locale/locale.js \ + locale/en.js iD.js: Makefile @rm -f $@ diff --git a/css/app.css b/css/app.css index e83c7152f..054863230 100644 --- a/css/app.css +++ b/css/app.css @@ -89,7 +89,7 @@ a:visited, a { } a:hover { - color:#154dff; + color:#597be7; } @@ -220,9 +220,10 @@ ul.link-list li:last-child { .fillD { background:rgba(0,0,0,.8); - color: white; + color: #a9a9a9; } + .fl { float: left;} .fr { float: right;} @@ -255,6 +256,9 @@ button { height:40px; cursor:url(../img/cursor-pointer.png) 6 1, auto; border-radius:4px; + -webkit-transition: background 100ms; + -moz-transition: background 100ms; + transition: background 100ms; } button:hover { @@ -279,11 +283,11 @@ button.minor { width: 20px; border: 0; box-shadow: none; - background-color: transparent; + background: rgba(0,0,0,.5); } button.minor:hover { - background: white; + background: #222; } button.centered { @@ -315,6 +319,8 @@ button.centered { border-radius:0 4px 4px 0; } +button.Browse .label { display: none;} + button.action { background: #7092ff; } @@ -399,17 +405,25 @@ button[disabled] .label { height: 40px; } -.icon.icon-pre-text { +.icon-pre-text { margin-right: 3px; } +.user-icon { + max-height: 20px; + max-width: 20px; + height: auto; + width: auto; + border-radius: 3px; +} + /* Definitions for every icon */ -.icon.browse { background-position: 0px -20px;} -.icon.add-point { background-position: -20px -20px;} -.icon.add-line { background-position: -40px -20px;} -.icon.add-area { background-position: -60px -20px;} -.icon.undo { background-position: -80px -20px;} -.icon.redo { background-position: -100px -20px;} +.icon.browse { background-position: 0px 0px;} +.icon.add-point { background-position: -20px 0px;} +.icon.add-line { background-position: -40px 0px;} +.icon.add-area { background-position: -60px 0px;} +.icon.undo { background-position: -80px 0px;} +.icon.redo { background-position: -100px 0px;} .icon.apply { background-position: -120px 0px;} .icon.save { background-position: -140px 0px;} @@ -419,20 +433,15 @@ button[disabled] .label { .icon.inspect { background-position: -220px 0px;} .icon.zoom-in { background-position: -240px 0px;} .icon.zoom-out { background-position: -260px 0px;} +.icon.plus { background-position: -240px 0px;} .icon.geocode { background-position: -280px 0px;} .icon.layers { background-position: -300px 0px;} .icon.avatar { background-position: -320px 0px;} .icon.nearby { background-position: -340px 0px;} .icon.geolocate { background-position: -360px 0px;} +.icon.warning { background-position: -380px 0px;} -.icon.invert.zoom-in { background-position: -240px -40px;} - -.icon.browse { background-position: 0px 0px;} -.icon.add-point { background-position: -20px 0px;} -.icon.add-line { background-position: -40px 0px;} -.icon.add-area { background-position: -60px 0px;} -.icon.undo { background-position: -80px 0px;} -.icon.redo { background-position: -100px 0px;} +.icon.close-modal { background-position: -200px -40px;} .fillD .icon.avatar { background-position: -320px -20px;} .fillD .icon.nearby { background-position: -340px -20px;} @@ -456,11 +465,23 @@ button[disabled] .icon.layers { background-position: -300px -40px;} button[disabled] .icon.avatar { background-position: -320px -40px;} button[disabled] .icon.nearby { background-position: -340px -40px;} -.icon.big-line { background-position: 0px -80px;} -.icon.big-point { background-position: -40px -80px;} -.icon.big-area { background-position: -80px -80px;} -.icon.big-vertex { background-position: -120px -80px;} -.icon.big-inspect { background-position: -160px -80px;} +.icon.big-line { background-position: 0px -80px;} +.icon.big-point { background-position: -40px -80px;} +.icon.big-area { background-position: -80px -80px;} +.icon.big-vertex { background-position: -120px -80px;} +.icon.big-inspect { background-position: -160px -80px;} +.icon.big-relation { background-position: -200px -80px;} + +.icon-operation-delete { background-position: 0px -140px;} +.icon-operation-circularize { background-position: -20px -140px;} +.icon-operation-straighten { background-position: -40px -140px;} +.icon-operation-split { background-position: -60px -140px;} +.icon-operation-unjoin { background-position: -80px -140px;} +.icon-operation-reverse { background-position: -100px -140px;} +.icon-operation-move { background-position: -120px -140px;} +.icon-operation-merge { background-position: -140px -140px;} +.icon-operation-orthogonalize { background-position: -160px -140px;} + /* Toggle icon is special */ .toggle.icon { background-position: 0px -180px;} @@ -593,19 +614,19 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} width: 60%; } -.inspector-inner .add-tag-row { - width: 100%; -} - -.inspector-inner .add-tag-row button { +.inspector-inner .add-tag { + width: 20%; + height: 30px; + border-top: 0; + background: rgba(0,0,0,.5); border-radius: 0 0 4px 4px; } +.inspector-inner .add-tag:hover { + background: rgba(0,0,0,.8); +} -.inspector-inner .add-tag { - width: 40%; - height: 30px; - border: 1px solid #ccc; - border-top: 0; +.inspector-inner .add-tag .label { + display: none; } /* Map Controls */ @@ -617,12 +638,13 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} .map-control button { width: 40px; - background: rgba(0,0,0,.8); - border-radius: 0 4px 4px 0; + background: rgba(0,0,0,.5); + border-radius: 0; + border-bottom: 1px solid rgba(0, 0, 0, 1); } .map-control button:hover { - background: rgba(0, 0, 0, .9); + background: rgba(0, 0, 0, .8); } .map-control button.active:hover { @@ -647,18 +669,16 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} .zoombuttons button.zoom-in { border-radius:0 4px 0 0; - border-bottom: 1px solid rgba(0, 0, 0, .5); } .zoombuttons button.zoom-out { border-top:0; - border-radius:0 0 4px 0; } /* Layer Switcher */ .layerswitcher-control { - top:210px; + top:190px; } .layerswitcher-control .adjustments button { @@ -729,7 +749,7 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} /* Geocoder */ .geocode-control { - top:160px; + top:150px; } .geocode-control input { @@ -738,8 +758,15 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} margin: 4px; } +/* Geolocator */ + .geolocate-control { - top:260px; + top:230px; +} + +.geolocate-control button { + border-radius: 0 0 4px 0; + border-bottom: 0; } /* Map @@ -862,9 +889,11 @@ div.typeahead a:first-child { display: inline-block; position:absolute; width: 50%; - left: 25%; + left: 0; + right: 0; + margin: auto; max-width: 600px; - top:80px; + top: 80px; z-index: 3; } @@ -900,6 +929,59 @@ div.typeahead a:first-child { left:0px; right:0px; top:0px; bottom:0px; } +.modal-section { + padding: 20px; +} + +.modal-section.header { + border-radius: 4px 4px 0 0; +} + +.modal-section:last-child { + border-radius: 0 0 4px 4px; +} + +.modal-section .buttons { + padding-top: 10px; + width: 100%; +} + +.modal-section img.wiki-image { + max-width: 100%; + max-height: 300px; + display: block; +} + +.modal-flash .content { + box-shadow: none; + border-radius: 4px; + background: #111; + color: #eee; +} + +.modal-flash .close-modal { + display:none; +} + +.loading-modal { + text-align: center; +} + +/* Commit Modal +------------------------------------------------------- */ + +.commit-modal .user-info { + display: inline-block; +} + +.commit-modal .commit-info { + margin-top: 10px; +} + +.commit-modal .user-info img { + float: left; +} + .commit-modal h3 small.count { margin-right: 10px; text-align: center; @@ -921,49 +1003,15 @@ div.typeahead a:first-child { max-height: 160px; } -.commit-modal .user-details { +.commit-modal .warning-section .changeset-list button { float: right; } -.user-icon { - max-width: 50px; - max-height: 50px; +.commit-section.modal-section { + padding-bottom: 0; } -.modal-section { - padding: 20px; -} - -.modal-section.header { - border-radius: 4px 4px 0 0; -} - -.modal-section:last-child { - border-radius: 0 0 4px 4px; -} - -.modal-section .buttons { - padding-top: 10px; - width: 100%; -} - -.modal-section img.wiki-image { - max-width: 400px; - max-height: 300px; - padding: 10px; - display: block; -} - -.modal-flash .content { - box-shadow: none; - border-radius: 4px; - background: #111; - color: #eee; -} - -.modal-flash .close-modal { - display:none; -} +.commit-section.modal-section:last-child { padding-bottom: 20px;} .changeset-list li { border-top:1px solid #ccc; @@ -987,8 +1035,12 @@ div.typeahead a:first-child { font:normal 12px/20px 'Helvetica Neue', Arial, sans-serif; } -.loading-modal { - text-align: center; +/* Success +------------------------------------------------------- */ +a.success-action { + display:inline-block; + padding:10px; + margin:10px; } /* Notices @@ -1053,17 +1105,17 @@ div.typeahead a:first-child { } .tooltip-inner { - text-align: left; - width: 200px; - font-size: 11px; - font-weight: bold; - line-height: 20px; - padding: 5px 10px; - color: #333; - background-color: white; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; + text-align: left; + width: 200px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + padding: 5px 10px; + color: #333; + background-color: white; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } .tooltip-arrow { @@ -1110,6 +1162,17 @@ div.typeahead a:first-child { left: 30px; } +.tooltip .keyhint { + float: right; + background: #eee; + font-size: 10px; + padding: 0 4px; + background:#aaa; + color:#fff; + border-radius: 2px; + margin-left: 4px; +} + .tail { pointer-events:none; position: absolute; @@ -1122,10 +1185,13 @@ div.typeahead a:first-child { border-radius: 4px; } +.radial-menu-background { + stroke: #aaa; + stroke-opacity: 0.4; +} + .radial-menu-item { - fill: white; - stroke: black; - stroke-width: 1; + fill: black; cursor:url(../img/cursor-pointer.png) 6 1, auto; } @@ -1143,6 +1209,17 @@ div.typeahead a:first-child { fill: rgba(255,255,255,.5); } +.radial-menu .icon { + pointer-events: none; +} + +.radial-menu-tooltip { + background: rgba(255, 255, 255, 0.8); + padding: 5px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} /* Media Queries ------------------------------------------------------- */ @@ -1151,5 +1228,5 @@ div.typeahead a:first-child { span.label {display: none;} /* override hide for save button */ .icon.icon-pre-text { margin-right: 0px;} - .save .label { display: block;} + .save .label, .apply .label { display: block;} } diff --git a/css/map.css b/css/map.css index 8f235bb18..7b3038d6c 100644 --- a/css/map.css +++ b/css/map.css @@ -16,7 +16,7 @@ g.point .shadow { transition: transform 100ms linear; -moz-transition: fill 100ms linear; } -g.point.hover .shadow { +.behavior-hover g.point.hover .shadow { fill: #E96666; fill-opacity: 0.3; } @@ -106,7 +106,7 @@ g.vertex .shadow { transition: transform 100ms linear; -moz-transition: fill 100ms linear; } -g.vertex.hover .shadow { +.behavior-hover g.vertex.hover .shadow { fill: #E96666; fill-opacity: 0.3; } @@ -120,7 +120,7 @@ g.vertex.selected .shadow { g.midpoint .fill { fill:#aaa; } -g.midpoint .fill.hover { +.behavior-hover g.midpoint .fill.hover { fill:#fff; stroke:#000; } @@ -133,7 +133,7 @@ g.midpoint .shadow { transition: transform 100ms linear; -moz-transition: fill 100ms linear; } -g.midpoint .shadow.hover { +.behavior-hover g.midpoint .shadow.hover { fill:#E96666; fill-opacity: 0.3; } @@ -161,7 +161,7 @@ path.shadow { -webkit-transition: stroke 100ms linear; } -path.shadow.hover { +.behavior-hover path.shadow.hover { stroke: #E96666; stroke-opacity: 0.3; } @@ -691,17 +691,17 @@ text.point.tag-amenity { cursor:url(../img/cursor-draw.png) 9 9, auto; } -.mode-draw-line .way, -.mode-draw-area .way, -.mode-add-line .way, -.mode-add-area .way { +.mode-draw-line .behavior-hover .way, +.mode-draw-area .behavior-hover .way, +.mode-add-line .behavior-hover .way, +.mode-add-area .behavior-hover .way { cursor:url(../img/cursor-draw-connect-line.png) 9 9, auto; } -.mode-draw-line .vertex, -.mode-draw-area .vertex, -.mode-add-line .vertex, -.mode-add-area .vertex { +.mode-draw-line .behavior-hover .vertex, +.mode-draw-area .behavior-hover .vertex, +.mode-add-line .behavior-hover .vertex, +.mode-add-area .behavior-hover .vertex { cursor:url(../img/cursor-draw-connect-vertex.png) 9 9, auto; } diff --git a/icons/unknown.png b/icons/unknown.png index a47dd947d..404602aa4 100644 Binary files a/icons/unknown.png and b/icons/unknown.png differ diff --git a/img/source/radial-menu.svg b/img/source/radial-menu.svg new file mode 100644 index 000000000..2fa1e44f9 --- /dev/null +++ b/img/source/radial-menu.svg @@ -0,0 +1,1835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Delete + + + + + Unjoin + Split way + + + + + + + + + + + + Delete + Circularize + Straighten + + Split + + + + Unjoin + Reverse + + + + + + + + + Move + + + + + + + + + + + + Merge + Orthogonalize + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/source/sprite.svg b/img/source/sprite.svg index 537a84226..01a28e513 100644 --- a/img/source/sprite.svg +++ b/img/source/sprite.svg @@ -9,11 +9,11 @@ xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="380" + width="420" height="200" id="svg12393" version="1.1" - inkscape:version="0.48.1 r9760" + inkscape:version="0.48.2 r9819" sodipodi:docname="sprite.svg" inkscape:export-filename="/Users/saman/work_repos/iD/img/sprite.png" inkscape:export-xdpi="90" @@ -38,25 +38,25 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="2.8284271" - inkscape:cx="173.1037" - inkscape:cy="123.12989" + inkscape:zoom="4" + inkscape:cx="332.2911" + inkscape:cy="175.13176" inkscape:document-units="px" inkscape:current-layer="layer12" showgrid="false" - inkscape:window-width="1560" - inkscape:window-height="922" - inkscape:window-x="223" + inkscape:window-width="1280" + inkscape:window-height="700" + inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="0" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" - showguides="false" + showguides="true" inkscape:guide-bbox="true" inkscape:snap-bbox="true" - inkscape:snap-nodes="false"> + inkscape:snap-nodes="true"> + + + @@ -173,7 +185,7 @@ image/svg+xml - + @@ -183,15 +195,6 @@ id="layer1" transform="translate(-25,-62.362183)" style="display:inline"> - + transform="translate(-25,3.0625001e-6)"> + - - - - - - - + style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> - - - - - - - - - - + style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375000000006;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 416.5,3.9999947 c -2.48528,0 -4.5,2.0147207 -4.5,4.5 0,0.7234907 0.19662,1.3943635 0.50001,2.0000053 L 409,13.999995 l 0,1.999999 2.00001,0 3.49999,-3.499997 c 0.60565,0.303377 1.27651,0.499995 2,0.499995 2.48528,0 4.5,-2.014712 4.5,-4.4999973 0,-2.4852793 -2.01472,-4.5 -4.5,-4.5 z m 0,1.9999993 c 1.38071,0 2.5,1.1192914 2.5,2.5000007 0,1.3807157 -1.11929,2.5000003 -2.5,2.5000003 -1.38071,0 -2.5,-1.1192846 -2.5,-2.5000003 0,-1.3807093 1.11929,-2.5000007 2.5,-2.5000007 z" + id="path47528" + inkscape:connector-curvature="0" /> + inkscape:connector-curvature="0" /> - - - - + transform="translate(-511.00001,-14)" + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"> + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.55555558;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"> + d="m 925.00003,-6.4444512 c -3.86599,0 -7,3.1340096 -7,6.99999958 0,1.12543002 0.30585,2.16901002 0.77778,3.11112002 l -5.44445,5.444436 0,3.1111096 3.11112,0 5.44444,-5.4444396 c 0.94211,0.47192 1.98568,0.77777 3.11111,0.77777 3.86599,0 7,-3.133996 7,-6.99999602 0,-3.86598998 -3.13401,-6.99999958 -7,-6.99999958 z m 0,3.1111096 c 2.14777,0 3.88889,1.74112 3.88889,3.88888998 0,2.14778002 -1.74112,3.88889002 -3.88889,3.88889002 -2.14777,0 -3.88889,-1.74111 -3.88889,-3.88889002 0,-2.14776998 1.74112,-3.88888998 3.88889,-3.88888998 z" + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.55555558;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> @@ -1080,5 +988,366 @@ id="path33359" d="m 354.5,22.999997 c -1.5,0 -2.5,2 -2.5,3 0,0.666667 0,1.333333 0,2 0,1 1,2.153847 1,2.153847 l 0,0.846153 -1.69231,0.384617 c -1.45419,0.330499 -2.02608,1.236079 -2.15384,2.76923 L 349,35.999998 l 12,0 -0.15385,-1.846154 c -0.12776,-1.533151 -0.69965,-2.438731 -2.15384,-2.76923 L 357,30.999997 l 0,-0.846153 c 0,0 1,-1.153847 1,-2.153847 0,-0.666667 0,-1.333333 0,-2 0,-1 -1,-3 -2.5,-3 z" style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/sprite.png b/img/sprite.png index e3037eebd..5922c06c1 100644 Binary files a/img/sprite.png and b/img/sprite.png differ diff --git a/index.html b/index.html index af436a86e..5f62b0f8f 100644 --- a/index.html +++ b/index.html @@ -73,6 +73,7 @@ + @@ -81,7 +82,7 @@ - + @@ -92,7 +93,6 @@ - @@ -104,8 +104,17 @@ + + + + + + + + + @@ -117,9 +126,13 @@ + + +
+ + @@ -86,7 +88,6 @@ - @@ -98,8 +99,17 @@ + + + + + + + + + @@ -111,6 +121,9 @@ + + + + @@ -158,6 +172,7 @@ + diff --git a/test/index_packaged.html b/test/index_packaged.html index c4eca2cca..aba99ba04 100644 --- a/test/index_packaged.html +++ b/test/index_packaged.html @@ -32,9 +32,9 @@ + - @@ -66,6 +66,7 @@ + diff --git a/test/rendering.html b/test/rendering.html index e5347d0b4..196122b2c 100644 --- a/test/rendering.html +++ b/test/rendering.html @@ -34,6 +34,20 @@ +
+ + +
+ + + @@ -105,6 +119,7 @@ }) .enter() .append('td') + .attr('class', function (d) { return d.mode === 'selected' ? 'mode-select' : 'mode-browse'; }) .append('svg') .attr('width', 200) .attr('height', 30) @@ -115,7 +130,7 @@ graph = iD.Graph([a, b, highway]); d3.select(this) - .attr('class', d.mode === 'selected' ? 'mode-select' : 'mode-browse') + .attr('class', 'behavior-hover') .call(vertices, graph, [a, b], filter) .call(lines, graph, [highway], filter) .call(midpoints, graph, [highway], filter) @@ -123,5 +138,67 @@ .classed(d.mode, d.mode !== 'base'); }); + +
z16z17
+ + + + + +
BaseSelected
+ + + diff --git a/test/spec/actions/add_midpoint.js b/test/spec/actions/add_midpoint.js new file mode 100644 index 000000000..1f749217e --- /dev/null +++ b/test/spec/actions/add_midpoint.js @@ -0,0 +1,22 @@ +describe("iD.actions.AddMidpoint", function () { + it("adds the node at the midpoint location", function () { + var node = iD.Node(), + midpoint = {loc: [1, 2], ways: []}, + graph = iD.actions.AddMidpoint(midpoint, node)(iD.Graph()); + + expect(graph.entity(node.id).loc).to.eql([1, 2]); + }); + + it("adds the node to all ways at the respective indexes", function () { + var node = iD.Node(), + a = iD.Node(), + b = iD.Node(), + w1 = iD.Way(), + w2 = iD.Way({nodes: [a.id, b.id]}), + midpoint = {loc: [1, 2], ways: [{id: w1.id, index: 0}, {id: w2.id, index: 1}]}, + graph = iD.actions.AddMidpoint(midpoint, node)(iD.Graph([a, b, w1, w2])); + + expect(graph.entity(w1.id).nodes).to.eql([node.id]); + expect(graph.entity(w2.id).nodes).to.eql([a.id, node.id, b.id]); + }); +}); diff --git a/test/spec/behavior/hover.js b/test/spec/behavior/hover.js index 817654d59..62d301d19 100644 --- a/test/spec/behavior/hover.js +++ b/test/spec/behavior/hover.js @@ -9,8 +9,23 @@ describe("iD.behavior.Hover", function() { container.remove(); }); + describe("#on", function () { + it("adds the .behavior-hover class to the selection", function () { + container.call(iD.behavior.Hover()); + expect(container).to.be.classed('behavior-hover') + }); + }); + + describe("#off", function () { + it("removes the .behavior-hover class from the selection", function () { + container.classed('behavior-hover', true); + container.call(iD.behavior.Hover().off); + expect(container).not.to.be.classed('behavior-hover') + }); + }); + describe("mouseover", function () { - it("adds the 'hover' class to all elements to which the same datum is bound", function () { + it("adds the .hover class to all elements to which the same datum is bound", function () { container.selectAll('span') .data(['a', 'b', 'a', 'b']) .enter().append('span').attr('class', Object); @@ -24,7 +39,7 @@ describe("iD.behavior.Hover", function() { }); describe("mouseout", function () { - it("removes the 'hover' class from all elements", function () { + it("removes the .hover class from all elements", function () { container.append('span').attr('class', 'hover'); container.call(iD.behavior.Hover()); diff --git a/test/spec/svg/midpoints.js b/test/spec/svg/midpoints.js new file mode 100644 index 000000000..c34ac0350 --- /dev/null +++ b/test/spec/svg/midpoints.js @@ -0,0 +1,52 @@ +describe("iD.svg.Midpoints", function () { + var surface, + projection = Object, + filter = d3.functor(true); + + beforeEach(function () { + surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg')) + .call(iD.svg.Surface()); + }); + + it("finds the location of the midpoints", function () { + var a = iD.Node({loc: [0, 0]}), + b = iD.Node({loc: [50, 0]}), + line = iD.Way({nodes: [a.id, b.id]}), + graph = iD.Graph([a, b, line]); + + surface.call(iD.svg.Midpoints(projection), graph, [line], filter); + + expect(surface.select('.midpoint').datum().loc).to.eql([25, 0]); + }); + + it("doesn't create midpoints on segments with pixel length less than 40", function () { + var a = iD.Node({loc: [0, 0]}), + b = iD.Node({loc: [39, 0]}), + line = iD.Way({nodes: [a.id, b.id]}), + graph = iD.Graph([a, b, line]); + + surface.call(iD.svg.Midpoints(projection), graph, [line], filter); + + expect(surface.selectAll('.midpoint')[0]).to.have.length(0); + }); + + it("binds a datum whose 'ways' property lists ways which include the segement", function () { + var a = iD.Node({loc: [0, 0]}), + b = iD.Node({loc: [50, 0]}), + c = iD.Node({loc: [1, 1]}), + d = iD.Node({loc: [2, 2]}), + l1 = iD.Way({nodes: [a.id, b.id]}), + l2 = iD.Way({nodes: [b.id, a.id]}), + l3 = iD.Way({nodes: [c.id, a.id, b.id, d.id]}), + l4 = iD.Way({nodes: [a.id, d.id, b.id]}), + graph = iD.Graph([a, b, c, d, l1, l2, l3, l4]), + ab = function (d) { return d.id === [a.id, b.id].sort().join("-"); }; + + surface.call(iD.svg.Midpoints(projection), graph, [l1, l2, l3, l4], filter); + + expect(surface.selectAll('.midpoint').filter(ab).datum().ways).to.eql([ + {id: l1.id, index: 1}, + {id: l2.id, index: 1}, + {id: l3.id, index: 2}]); + }); +});