Merge branch 'develop' into touch-walkthrough-update

This commit is contained in:
Quincy Morgan
2020-06-29 11:14:59 -04:00
17 changed files with 212 additions and 83 deletions
+90 -28
View File
@@ -7,14 +7,16 @@ fail to serve some proportion of mappers. Broadly speaking, iD should strive to
follow [universal design](https://en.wikipedia.org/wiki/Universal_design) principles.
This is a living document that details the usability of iD across a number of dimensions,
with the intent of identifying and addressing problem areas.
with the intent of identifying and addressing problem areas. Since there are always more
factors to consider, no part of this document should be considered "complete".
Symbols used in this document:
- ✅ Full support
- 🟩 Full support assumed but unverified
- 🟩 Full support assumed, but not sufficiently tested
- 🟠 Partial support
- ❌ No appreciable support
- 🤷 Unknown support, none is assumed
## Browser Compatibility
@@ -26,18 +28,78 @@ should fallback gracefully without breaking other aspects of the app.
This table covers high-level compatibility, with individual features to be detailed
elsewhere in this document.
| | Browser | Notes |
|---|---|---|
| ✅ | Chrome | |
| ✅* | Firefox | *Minor known issues ([#7132]) |
| ✅ | Safari | |
| 🟩 | Opera | Infrequently tested |
| 🟩 | Edge | Infrequently tested |
| 🟠 | Internet Explorer | Infrequently tested. IE has been discontinued, but IE 11 is still maintained. iD polyfills ES6 features on IE 11, with varying success. |
| 🟠 | Mobile browsers | iD has not yet been fully optimized for mobile devices, but some editing is usually possible. |
| | | Browser | Notes | Issues |
|---|---|---|---|---|
| ✅ | ![chrome logo] | Chrome | |
| ✅* | ![firefox logo] | Firefox | \*Minor known issues | [#7132] |
| ✅ | ![safari logo] | Safari | |
| 🟩 | ![opera logo] | Opera | |
| 🟩 | ![edge logo] | Edge | |
| 🟠 | ![ie logo] | Internet Explorer | IE has been discontinued, but IE 11 is still maintained. iD polyfills ES6 features on IE 11, with varying success. |
| 🟩 | 🌐 | Others | iD should run without issue on any desktop browser implementing modern web standards. |
| 🟠 | 📱 | Mobile browsers | iD has not yet been fully optimized for mobile devices, but some editing is usually possible. |
[safari logo]: https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/Safari_browser_logo.svg/30px-Safari_browser_logo.svg.png
[opera logo]: https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Opera_browser_logo_2013_vector.svg/30px-Opera_browser_logo_2013_vector.svg.png
[chrome logo]: https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Google_Chrome_icon_%28September_2014%29.svg/30px-Google_Chrome_icon_%28September_2014%29.svg.png
[firefox logo]: https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/Firefox_logo%2C_2019.svg/30px-Firefox_logo%2C_2019.svg.png
[edge logo]: https://upload.wikimedia.org/wikipedia/commons/thumb/b/b8/Microsoft_Edge_logo_%282015%E2%80%932019%29.svg/30px-Microsoft_Edge_logo_%282015%E2%80%932019%29.svg.png
[ie logo]: https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Internet_Explorer_10%2B11_logo.svg/30px-Internet_Explorer_10%2B11_logo.svg.png
[#7132]: https://github.com/openstreetmap/iD/issues/7132
## Input Device Support
iD has traditionally assumed the mapper will be interacting via a mouse and keyboard,
but realistically people want or need to use various other [input devices](https://en.wikipedia.org/wiki/Input_device).
iD relies on modern [pointer events](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events) for some interactions, so
some devices may see degraded functionality on older browsers.
### Setups
The following table lists iD's usability for different setups. A setup is where
a mapper is using only the device(s) given in the row.
A setup with "full support" offers functionality equivalent to that of the
highest-functioning setup (generally mouse and keyboard).
Certain functions may be accessed differently on different setups,
such as opening the edit menu via long-pressing instead of right-clicking.
| | | Input Setup | Notes |
|---|---|---|---|
| ✅ | 🖱⌨️ | [Mouse](https://en.wikipedia.org/wiki/Computer_mouse) + [keyboard](https://en.wikipedia.org/wiki/Computer_keyboard) | iD's original input paradigm. Any mouse-like device such as a [trackpad](https://en.wikipedia.org/wiki/Touchpad), [trackball](https://en.wikipedia.org/wiki/Trackball), or [pointing stick](https://en.wikipedia.org/wiki/Pointing_stick) is grouped into "mouse" for this table |
| ❌ | ⌨️ | Keyboard only | Not all elements can necessarily be keyed to. Key traps may exists. Geometry editing isn't possible |
| 🟠 | 🖱 | Mouse only | The primary [mouse button](https://en.wikipedia.org/wiki/Mouse_button) (e.g. left click) alone is sufficient. Multiselection and disabling of node-snapping aren't possible |
| 🟠 | 🖐 | [Multi-touch](https://en.wikipedia.org/wiki/Multi-touch) on a [touchscreen](https://en.wikipedia.org/wiki/Touchscreen) | Move and rotate aren't possible |
| 🟠 | ✍️ | [Stylus](https://en.wikipedia.org/wiki/Stylus_(computing)) on a touchscreen | Move, rotate, and multiselection aren't possible |
| 🤷 | ✍️🔲 | Stylus on a [graphics tablet](https://en.wikipedia.org/wiki/Graphics_tablet) | |
| 🤷 | 🎮 | [Gamepad](https://en.wikipedia.org/wiki/Gamepad) | |
| 🤷 | 🗣 | [Voice](https://en.wikipedia.org/wiki/Voice_user_interface) | Tools like [Voice Control on macOS](https://support.apple.com/en-us/HT210539) and [Windows Speech Recognition](https://en.wikipedia.org/wiki/Windows_Speech_Recognition) allow navigating webpages with voice commands to some degree |
| 🤷 | 🔘 | [Switch](https://en.wikipedia.org/wiki/Switch_access) | Tools like [Switch Control on macOS](https://support.apple.com/en-us/HT202865) can theoretically replicate mouse and keyboard interactions in most apps |
### Devices
This table details iD's support for specific classes of input devices.
"Full support" for a device means that iD reasonably handles its entire range of input on supported platforms. But unlike the "setups" table above, a given device is not necessarily expected to perform all of iD's functions.
It's impractical to ensure every single input device works as expected, so the table only reflects the support status to the best of our knowledge.
| | Input Device | Notes | Issues |
|---|---|---|---|
| ✅ | Single-button mouse | E.g. [Chester Mouse](https://duckduckgo.com/?q=chester+one+button+mouse&iar=images&iax=images&ia=images). Primary click (e.g. left-click) can be used for all pointer interactions. A long-click on map features opens the edit menu |
| ✅ | Multi-button mouse | Secondary click (e.g. right-click) can be used on map features to open the edit menu. Middle click, etc., are not needed by iD but are passed through to the browser |
| ✅ | Multi-touch mouse | E.g. [Magic Mouse](https://en.wikipedia.org/wiki/Magic_Mouse). 2D scrolling in the map is treated as panning, not zooming |
| 🟠 | Vertical [scroll wheel](https://en.wikipedia.org/wiki/Scroll_wheel) | Should zoom the map in and out | [#5550](https://github.com/openstreetmap/iD/issues/5550) |
| ❌ | Horizontal scroll wheel | Currently does nothing in the map | [#7134](https://github.com/openstreetmap/iD/issues/7134) |
| 🤷 | Scroll ball | E.g. in [Apple Mighty Mouse](https://en.wikipedia.org/wiki/Apple_Mighty_Mouse) |
| 🟩 | Trackball | |
| 🟩 | Trackpad | |
| ✅ | Multi-touch trackpad | E.g. [Magic Trackpad](https://en.wikipedia.org/wiki/Magic_Trackpad). Pinch-to-zoom and scroll-to-pan are supported in the map |
| 🟩 | Pointing stick | |
| ✅ | Keyboard | |
## Language Support
English is the language of tags and relation roles in the OpenStreetMap database.
@@ -56,7 +118,7 @@ for more info.
| ❌ | Base language fallback | E.g. if `pt_BR` is incomplete, `pt` should be tried before `en` |
| ❌ | Custom fallback language | If the preferred language is incomplete, a user-specified one should be tried before `en` (e.g. `kk``ru`) |
| ✅ | Locale URL parameters | `locale` and `rtl` can be used to manually set iD's locale preferences. See the [API](API.md#url-parameters) |
| 🟩 | Right-to-left layouts | Infrequently tested. Used for languages like Hebrew and Arabic |
| 🟩 | Right-to-left layouts | Used for languages like Hebrew and Arabic |
### Translatability
@@ -64,22 +126,22 @@ The following table details which interface elements can adapt to the mapper's
language preferences. This doesn't account for whether they've actually been
translated to one or more languages.
| | Interface Element | Notes |
|---|---|---|
| ✅ | Labels and descriptions | |
| ✅ | Help docs and walkthrough | |
| ✅ | Letter hotkeys | E.g. <kbd>S</kbd> for Straighten makes sense in English, but not every language |
| ✅ | Preset names and search terms | |
| 🟠 | Fields | Combo fields may show raw tag values. The Wikipedia field lists Wiki names in their native languages |
| ❌ | Tags | OpenStreetMap tags are English-only as a limitation of the database |
| ❌ | Relation member roles | OpenStreetMap roles are also limited to English |
| ✅ | Imagery metadata | |
| 🟠 | Locator overlay | This layer shows feature labels in their local languages |
| ✅ | OSM community index | |
| ✅ | iD validation issues | |
| ✅ | KeepRight issues | |
| ✅ | ImproveOSM issues | |
| ✅ | Osmose issues | Translated strings are [provided by Osmose](https://www.transifex.com/openstreetmap-france/osmose/) itself, not iD |
| | Interface Element | Notes | Issues |
|---|---|---|---|
| ✅ | Labels and descriptions | | |
| ✅ | Help docs and walkthrough | | |
| ✅ | Letter hotkeys | E.g. <kbd>S</kbd> for Straighten makes sense in English, but not every language | |
| ✅ | Preset names and search terms | | |
| 🟠 | Fields | Combo fields may show raw tag values. The Wikipedia field lists Wiki names in their native languages | [#2708](https://github.com/openstreetmap/iD/issues/2708) |
| ❌ | Tags | OpenStreetMap tags are English-only as a limitation of the database | |
| ❌ | Relation member roles | OpenStreetMap roles are also limited to English | |
| ✅ | Imagery metadata | | |
| 🟠 | Locator overlay | This layer shows feature labels in their local languages | [#7737](https://github.com/openstreetmap/iD/issues/7737) |
| ✅ | OSM community index | | |
| ✅ | iD validation issues | | |
| ✅ | KeepRight issues | | |
| ✅ | ImproveOSM issues | | |
| ✅ | Osmose issues | Translated strings are [provided by Osmose](https://www.transifex.com/openstreetmap-france/osmose/) itself, not iD | |
### Language Coverage
-12
View File
@@ -2583,21 +2583,9 @@ img.tag-reference-wiki-image {
}
.form-field-input-member > input.member-role {
border-radius: 0 0 0 4px;
}
.ideditor[dir='rtl'] .form-field-input-member > input.member-role {
border-radius: 0 0 4px 0;
}
.member-incomplete .form-field-input-member > input.member-role,
.ideditor[dir='rtl'] .member-incomplete .form-field-input-member > input.member-role {
border-radius: 0 0 4px 4px;
}
.member-incomplete .member-delete {
display: none;
}
.member-row-new .member-entity-input {
flex: 1 1 100%;
border-radius: 4px 4px 0 0;
+2
View File
@@ -315,6 +315,7 @@ en:
vertex: Moved a node in a way.
line: Moved a line.
area: Moved an area.
relation: Moved a relation.
multiple: Moved multiple features.
incomplete_relation:
single: This feature can't be moved because it hasn't been fully downloaded.
@@ -371,6 +372,7 @@ en:
line: Rotated a line.
area: Rotated an area.
multiple: Rotated multiple features.
relation: Rotated a relation.
incomplete_relation:
single: This feature can't be rotated because it hasn't been fully downloaded.
multiple: These features can't be rotated because they haven't been fully downloaded.
+4
View File
@@ -247,6 +247,10 @@
"old": {"building": "household"},
"replace": {"building": "house"}
},
{
"old": {"building": "pavillion"},
"replace": {"building": "pavilion"}
},
{
"old": {"building:color": "*"},
"replace": {"building:colour": "$1"}
+3 -2
View File
@@ -4664,8 +4664,9 @@ en:
terms: '<translate with synonyms or related terms for ''Craft'', separated by commas>'
craft/agricultural_engines:
# craft=agricultural_engines
name: Argricultural Engines Mechanic
terms: '<translate with synonyms or related terms for ''Argricultural Engines Mechanic'', separated by commas>'
name: Agricultural Engines Mechanic
# 'terms: combines,farm equipment,harvesters,tractors'
terms: '<translate with synonyms or related terms for ''Agricultural Engines Mechanic'', separated by commas>'
craft/basket_maker:
# craft=basket_maker
name: Basket Maker
+1 -1
View File
@@ -395,7 +395,7 @@
"craft": {"icon": "temaki-tools", "fields": ["name", "craft", "operator", "address", "building_area", "opening_hours", "opening_hours/covid19"], "moreFields": ["air_conditioning", "building/levels_building", "ele", "email", "fax", "gnis/feature_id", "height_building", "internet_access", "internet_access/fee", "internet_access/ssid", "level", "phone", "product", "ref/vatin", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"craft": "*"}, "terms": [], "name": "Craft"},
"craft/locksmith": {"icon": "maki-marker-stroked", "geometry": ["point", "area"], "tags": {"craft": "locksmith"}, "reference": {"key": "shop", "value": "locksmith"}, "name": "Locksmith", "searchable": false},
"craft/tailor": {"icon": "temaki-needle_and_spool", "geometry": ["point", "area"], "tags": {"craft": "tailor"}, "reference": {"key": "shop", "value": "tailor"}, "name": "Tailor", "searchable": false},
"craft/agricultural_engines": {"icon": "temaki-tools", "geometry": ["point", "area"], "tags": {"craft": "agricultural_engines"}, "name": "Argricultural Engines Mechanic"},
"craft/agricultural_engines": {"icon": "temaki-tools", "geometry": ["point", "area"], "tags": {"craft": "agricultural_engines"}, "terms": ["combines", "farm equipment", "harvesters", "tractors"], "name": "Agricultural Engines Mechanic"},
"craft/basket_maker": {"icon": "temaki-vase", "geometry": ["point", "area"], "tags": {"craft": "basket_maker"}, "name": "Basket Maker"},
"craft/beekeeper": {"icon": "maki-farm", "geometry": ["point", "area"], "tags": {"craft": "beekeeper"}, "name": "Beekeeper"},
"craft/blacksmith": {"icon": "temaki-anvil_and_hammer", "geometry": ["point", "area"], "tags": {"craft": "blacksmith"}, "name": "Blacksmith"},
@@ -7,5 +7,11 @@
"tags": {
"craft": "agricultural_engines"
},
"name": "Argricultural Engines Mechanic"
"terms": [
"combines",
"farm equipment",
"harvesters",
"tractors"
],
"name": "Agricultural Engines Mechanic"
}
+2 -1
View File
@@ -391,7 +391,7 @@
{"key": "craft", "description": "🄿 Craft, 🄵 Type", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/tools.svg"},
{"key": "craft", "value": "locksmith", "description": "🄿 Locksmith (unsearchable)", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/mapbox/maki/icons/marker-stroked-15.svg"},
{"key": "craft", "value": "tailor", "description": "🄿 Tailor (unsearchable)", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/needle_and_spool.svg"},
{"key": "craft", "value": "agricultural_engines", "description": "🄿 Argricultural Engines Mechanic", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/tools.svg"},
{"key": "craft", "value": "agricultural_engines", "description": "🄿 Agricultural Engines Mechanic", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/tools.svg"},
{"key": "craft", "value": "basket_maker", "description": "🄿 Basket Maker", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/vase.svg"},
{"key": "craft", "value": "beekeeper", "description": "🄿 Beekeeper", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/mapbox/maki/icons/farm-15.svg"},
{"key": "craft", "value": "blacksmith", "description": "🄿 Blacksmith", "object_types": ["node", "area"], "icon_url": "https://cdn.jsdelivr.net/gh/ideditor/temaki/icons/anvil_and_hammer.svg"},
@@ -2060,6 +2060,7 @@
{"key": "building", "value": "family_house", "description": "🄳 ➜ building=house"},
{"key": "building", "value": "home", "description": "🄳 ➜ building=house"},
{"key": "building", "value": "household", "description": "🄳 ➜ building=house"},
{"key": "building", "value": "pavillion", "description": "🄳 ➜ building=pavilion"},
{"key": "building:color", "description": "🄳 ➜ building:colour=*"},
{"key": "building:height", "description": "🄳 ➜ height=*"},
{"key": "building:material", "value": "Brick", "description": "🄳 ➜ building:material=brick"},
+5 -3
View File
@@ -411,6 +411,7 @@
"vertex": "Moved a node in a way.",
"line": "Moved a line.",
"area": "Moved an area.",
"relation": "Moved a relation.",
"multiple": "Moved multiple features."
},
"incomplete_relation": {
@@ -486,7 +487,8 @@
"annotation": {
"line": "Rotated a line.",
"area": "Rotated an area.",
"multiple": "Rotated multiple features."
"multiple": "Rotated multiple features.",
"relation": "Rotated a relation."
},
"incomplete_relation": {
"single": "This feature can't be rotated because it hasn't been fully downloaded.",
@@ -6711,8 +6713,8 @@
"name": "Tailor"
},
"craft/agricultural_engines": {
"name": "Argricultural Engines Mechanic",
"terms": ""
"name": "Agricultural Engines Mechanic",
"terms": "combines,farm equipment,harvesters,tractors"
},
"craft/basket_maker": {
"name": "Basket Maker",
+5 -2
View File
@@ -45,7 +45,10 @@ export function actionExtract(entityID) {
var keysToRetain = ['area'];
var buildingKeysToRetain = ['architect', 'building', 'height', 'layer'];
var centroid = d3_geoCentroid(entity.asGeoJSON(graph));
var extractedLoc = d3_geoCentroid(entity.asGeoJSON(graph));
if (!extractedLoc || !isFinite(extractedLoc[0]) || !isFinite(extractedLoc[1])) {
extractedLoc = entity.extent(graph).center();
}
var isBuilding = entity.tags.building && entity.tags.building !== 'no';
@@ -87,7 +90,7 @@ export function actionExtract(entityID) {
entityTags.area = 'yes';
}
var replacement = osmNode({ loc: centroid, tags: pointTags });
var replacement = osmNode({ loc: extractedLoc, tags: pointTags });
graph = graph.replace(replacement);
extractedNodeID = replacement.id;
+28 -3
View File
@@ -1,6 +1,6 @@
import { geoPolygonContainsPolygon } from '../geo';
import { osmJoinWays, osmRelation } from '../osm';
import { utilArrayGroupBy, utilObjectOmit } from '../util';
import { utilArrayGroupBy, utilArrayIntersection, utilObjectOmit } from '../util';
export function actionMergePolygon(ids, newRelationId) {
@@ -114,10 +114,35 @@ export function actionMergePolygon(ids, newRelationId) {
action.disabled = function(graph) {
var entities = groupEntities(graph);
if (entities.other.length > 0 ||
entities.closedWay.length + entities.multipolygon.length < 2)
entities.closedWay.length + entities.multipolygon.length < 2) {
return 'not_eligible';
if (!entities.multipolygon.every(function(r) { return r.isComplete(graph); }))
}
if (!entities.multipolygon.every(function(r) { return r.isComplete(graph); })) {
return 'incomplete_relation';
}
if (!entities.multipolygon.length) {
var sharedMultipolygons = [];
entities.closedWay.forEach(function(way, i) {
if (i === 0) {
sharedMultipolygons = graph.parentMultipolygons(way);
} else {
sharedMultipolygons = utilArrayIntersection(sharedMultipolygons, graph.parentMultipolygons(way));
}
});
sharedMultipolygons = sharedMultipolygons.filter(function(relation) {
return relation.members.length === entities.closedWay.length;
});
if (sharedMultipolygons.length) {
// don't create a new multipolygon if it'd be redundant
return 'not_eligible';
}
} else if (entities.closedWay.some(function(way) {
return utilArrayIntersection(graph.parentMultipolygons(way), entities.multipolygon).length;
})) {
// don't add a way to a multipolygon again if it's already a member
return 'not_eligible';
}
};
+2 -3
View File
@@ -21,10 +21,9 @@ export function operationExtract(context, selectedIDs) {
if (entity.type === 'node' && graph.parentWays(entity).length === 0) return;
var geometry = graph.geometry(entityID);
if (geometry === 'area' || geometry === 'line') {
if (entity.type !== 'node') {
var preset = presetManager.match(entity, graph);
// only allow extraction from ways/multipolygons if the preset supports points
// only allow extraction from ways/relations if the preset supports points
if (preset.geometry.indexOf('point') === -1) return;
}
+14 -9
View File
@@ -14,19 +14,24 @@ export function operationMerge(context, selectedIDs) {
var _action = getAction();
function getAction() {
// prefer a non-disabled action first
var join = actionJoin(selectedIDs);
if (join.disabled(context.graph()) !== 'not_eligible') {
return join;
}
if (!join.disabled(context.graph())) return join;
var merge = actionMerge(selectedIDs);
if (merge.disabled(context.graph()) !== 'not_eligible') {
return merge;
}
if (!merge.disabled(context.graph())) return merge;
var mergePolygon = actionMergePolygon(selectedIDs);
if (mergePolygon.disabled(context.graph()) !== 'not_eligible') {
return mergePolygon;
}
if (!mergePolygon.disabled(context.graph())) return mergePolygon;
var mergeNodes = actionMergeNodes(selectedIDs);
if (!mergeNodes.disabled(context.graph())) return mergeNodes;
// otherwise prefer an action with an interesting disabled reason
if (join.disabled(context.graph()) !== 'not_eligible') return join;
if (merge.disabled(context.graph()) !== 'not_eligible') return merge;
if (mergePolygon.disabled(context.graph()) !== 'not_eligible') return mergePolygon;
return mergeNodes;
}
+10 -1
View File
@@ -48,7 +48,16 @@ export function uiEditMenu(context) {
var showLabels = isTouchMenu;
var buttonHeight = showLabels ? 32 : 34;
var menuWidth = showLabels ? 172 : 44;
var menuWidth;
if (showLabels) {
// Get a general idea of the width based on the length of the label
menuWidth = 52 + Math.min(120, 6 * Math.max.apply(Math, ops.map(function(op) {
return op.title.length;
})));
} else {
menuWidth = 44;
}
var menuLeft = displayOnLeft(viewport);
offset[0] = menuLeft ? -1 * (_menuSideMargin + menuWidth) : _menuSideMargin;
+3
View File
@@ -59,6 +59,9 @@ export function uiInit(context) {
container
.on('click.ui', function() {
// we're only concerned with the primary mouse button
if (d3_event.button !== 0) return;
if (!d3_event.composedPath) return;
// some targets have default click events we don't want to override
+7 -7
View File
@@ -189,6 +189,13 @@ export function uiSectionRawMemberEditor(context) {
.attr('class', 'member-entity-name')
.text(function(d) { return utilDisplayName(d.member); });
label
.append('button')
.attr('tabindex', -1)
.attr('title', t('icons.remove'))
.attr('class', 'remove member-delete')
.call(svgIcon('#iD-operation-delete'));
label
.append('button')
.attr('class', 'member-zoom')
@@ -235,13 +242,6 @@ export function uiSectionRawMemberEditor(context) {
.attr('placeholder', t('inspector.role'))
.call(utilNoAuto);
wrapEnter
.append('button')
.attr('tabindex', -1)
.attr('title', t('icons.remove'))
.attr('class', 'remove form-field-button member-delete')
.call(svgIcon('#iD-operation-delete'));
if (taginfo) {
wrapEnter.each(bindTypeahead);
}
+29 -10
View File
@@ -61,6 +61,16 @@ export function uiSectionRawMembershipEditor(context) {
context.enter(modeSelect(context, [d.relation.id]));
}
function zoomToRelation(d) {
d3_event.preventDefault();
var entity = context.entity(d.relation.id);
context.map().zoomToEase(entity);
// highlight the relation in case it wasn't previously on-screen
utilHighlightEntities([d.relation.id], true, context);
}
function changeRole(d) {
if (d === 0) return; // called on newrow (shoudn't happen)
@@ -236,14 +246,16 @@ export function uiSectionRawMembershipEditor(context) {
.attr('class', 'field-label')
.attr('for', function(d) {
return d.domId;
})
});
var labelLink = labelEnter
.append('span')
.attr('class', 'label-text')
.append('a')
.attr('href', '#')
.on('click', selectRelation);
labelEnter
labelLink
.append('span')
.attr('class', 'member-entity-type')
.text(function(d) {
@@ -251,11 +263,25 @@ export function uiSectionRawMembershipEditor(context) {
return (matched && matched.name()) || t('inspector.relation');
});
labelEnter
labelLink
.append('span')
.attr('class', 'member-entity-name')
.text(function(d) { return utilDisplayName(d.relation); });
labelEnter
.append('button')
.attr('tabindex', -1)
.attr('class', 'remove member-delete')
.call(svgIcon('#iD-operation-delete'))
.on('click', deleteMembership);
labelEnter
.append('button')
.attr('class', 'member-zoom')
.attr('title', t('icons.zoom_to'))
.call(svgIcon('#iD-icon-framed-dot', 'monochrome'))
.on('click', zoomToRelation);
var wrapEnter = itemsEnter
.append('div')
.attr('class', 'form-field-input-wrap form-field-input-member');
@@ -273,13 +299,6 @@ export function uiSectionRawMembershipEditor(context) {
.on('blur', changeRole)
.on('change', changeRole);
wrapEnter
.append('button')
.attr('tabindex', -1)
.attr('class', 'remove form-field-button member-delete')
.call(svgIcon('#iD-operation-delete'))
.on('click', deleteMembership);
if (taginfo) {
wrapEnter.each(bindTypeahead);
}