mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-23 08:39:56 +02:00
Merge branch 'master' into ignoring-issues
This commit is contained in:
@@ -148,6 +148,14 @@
|
||||
"old": {"amenity": "youth_centre"},
|
||||
"replace": {"amenity": "community_centre", "community_centre:for": "juvenile"}
|
||||
},
|
||||
{
|
||||
"old": {"artwork": "*"},
|
||||
"replace": {"artwork_type": "$1"}
|
||||
},
|
||||
{
|
||||
"old": {"artwork:type": "*"},
|
||||
"replace": {"artwork_type": "$1"}
|
||||
},
|
||||
{
|
||||
"old": {"barrier": "curb"},
|
||||
"replace": {"barrier": "kerb"}
|
||||
|
||||
@@ -4685,6 +4685,7 @@ en:
|
||||
landuse/meadow:
|
||||
# landuse=meadow
|
||||
name: Meadow
|
||||
# 'terms: grazing,hay field,pasture'
|
||||
terms: '<translate with synonyms or related terms for ''Meadow'', separated by commas>'
|
||||
landuse/military:
|
||||
# landuse=military
|
||||
@@ -7110,6 +7111,21 @@ en:
|
||||
name: Artwork
|
||||
# 'terms: mural,sculpture,statue'
|
||||
terms: '<translate with synonyms or related terms for ''Artwork'', separated by commas>'
|
||||
tourism/artwork/bust:
|
||||
# 'tourism=artwork, artwork_type=bust'
|
||||
name: Bust
|
||||
# 'terms: figure'
|
||||
terms: '<translate with synonyms or related terms for ''Bust'', separated by commas>'
|
||||
tourism/artwork/graffiti:
|
||||
# 'tourism=artwork, artwork_type=graffiti'
|
||||
name: Graffiti
|
||||
# 'terms: Street Artwork,Guerilla Artwork,Graffiti Artwork'
|
||||
terms: '<translate with synonyms or related terms for ''Graffiti'', separated by commas>'
|
||||
tourism/artwork/installation:
|
||||
# 'tourism=artwork, artwork_type=installation'
|
||||
name: Art Installation
|
||||
# 'terms: interactive art,intervention art,modern art'
|
||||
terms: '<translate with synonyms or related terms for ''Art Installation'', separated by commas>'
|
||||
tourism/artwork/mural:
|
||||
# 'tourism=artwork, artwork_type=mural'
|
||||
name: Mural
|
||||
|
||||
@@ -547,7 +547,7 @@
|
||||
"landuse/industrial/scrap_yard": {"icon": "maki-car", "fields": ["name", "operator", "address", "opening_hours"], "geometry": ["point", "area"], "tags": {"industrial": "scrap_yard"}, "addTags": {"landuse": "industrial", "industrial": "scrap_yard"}, "removeTags": {"landuse": "industrial", "industrial": "scrap_yard"}, "reference": {"key": "industrial", "value": "scrap_yard"}, "terms": ["car", "junk", "metal", "salvage", "scrap", "u-pull-it", "vehicle", "wreck", "yard"], "name": "Scrap Yard"},
|
||||
"landuse/industrial/slaughterhouse": {"icon": "maki-slaughterhouse", "fields": ["name", "operator", "address", "building_area", "opening_hours"], "geometry": ["point", "area"], "tags": {"industrial": "slaughterhouse"}, "addTags": {"landuse": "industrial", "industrial": "slaughterhouse"}, "removeTags": {"landuse": "industrial", "industrial": "slaughterhouse"}, "reference": {"key": "industrial", "value": "slaughterhouse"}, "terms": ["abattoir", "beef", "butchery", "calf", "chicken", "cow", "killing house", "meat", "pig", "pork", "poultry", "shambles", "stockyard"], "name": "Slaughterhouse"},
|
||||
"landuse/landfill": {"geometry": ["area"], "fields": ["name"], "moreFields": ["address", "website", "phone", "email", "fax"], "tags": {"landuse": "landfill"}, "terms": ["dump"], "name": "Landfill"},
|
||||
"landuse/meadow": {"icon": "maki-garden", "geometry": ["area"], "fields": ["name"], "tags": {"landuse": "meadow"}, "terms": [], "name": "Meadow"},
|
||||
"landuse/meadow": {"icon": "maki-garden", "geometry": ["area"], "fields": ["name"], "tags": {"landuse": "meadow"}, "terms": ["grazing", "hay field", "pasture"], "name": "Meadow"},
|
||||
"landuse/military": {"icon": "temaki-military", "fields": ["name"], "moreFields": ["address", "website", "phone", "email", "fax"], "geometry": ["area"], "tags": {"landuse": "military"}, "terms": [], "matchScore": 0.9, "name": "Military Area"},
|
||||
"landuse/military/airfield": {"icon": "tnp-2009265", "fields": ["name", "iata", "icao"], "geometry": ["point", "area"], "tags": {"military": "airfield"}, "addTags": {"aeroway": "aerodrome", "landuse": "military", "military": "airfield"}, "removeTags": {"aeroway": "aerodrome", "landuse": "military", "military": "airfield"}, "reference": {"key": "military", "value": "airfield"}, "terms": ["aerodrome", "aeroway", "air force", "airplane", "airport", "army", "base", "bomb", "fight", "force", "guard", "heli*", "jet", "marine", "navy", "plane", "troop", "war"], "name": "Military Airfield"},
|
||||
"landuse/military/barracks": {"icon": "temaki-military", "fields": ["name", "building_area"], "geometry": ["point", "area"], "tags": {"military": "barracks"}, "addTags": {"landuse": "military", "military": "barracks"}, "removeTags": {"landuse": "military", "military": "barracks"}, "terms": ["air force", "army", "base", "fight", "force", "guard", "marine", "navy", "troop", "war"], "name": "Barracks"},
|
||||
@@ -1066,9 +1066,12 @@
|
||||
"tourism/apartment": {"icon": "maki-lodging", "fields": ["name", "operator", "address", "building_area", "rooms", "internet_access", "internet_access/fee"], "moreFields": ["building/levels_building", "height_building", "email", "fax", "internet_access/ssid", "payment_multi", "phone", "reservation", "smoking", "website", "wheelchair"], "geometry": ["point", "area"], "tags": {"tourism": "apartment"}, "name": "Guest Apartment / Condo"},
|
||||
"tourism/aquarium": {"icon": "maki-aquarium", "fields": ["name", "operator", "address", "building_area", "opening_hours"], "moreFields": ["fee", "internet_access", "internet_access/fee", "internet_access/ssid", "payment_multi_fee", "smoking", "website", "phone", "email", "fax", "wheelchair"], "geometry": ["point", "area"], "terms": ["fish", "sea", "water"], "tags": {"tourism": "aquarium"}, "name": "Aquarium"},
|
||||
"tourism/artwork": {"icon": "maki-art-gallery", "fields": ["name", "artwork_type", "artist"], "moreFields": ["material", "website"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork"}, "terms": ["mural", "sculpture", "statue"], "name": "Artwork"},
|
||||
"tourism/artwork/bust": {"icon": "fas-user-alt", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex"], "tags": {"tourism": "artwork", "artwork_type": "bust"}, "reference": {"key": "artwork_type"}, "terms": ["figure"], "name": "Bust"},
|
||||
"tourism/artwork/graffiti": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "graffiti"}, "reference": {"key": "artwork_type"}, "terms": ["Street Artwork", "Guerilla Artwork", "Graffiti Artwork"], "name": "Graffiti"},
|
||||
"tourism/artwork/installation": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "installation"}, "reference": {"key": "artwork_type"}, "terms": ["interactive art", "intervention art", "modern art"], "name": "Art Installation"},
|
||||
"tourism/artwork/mural": {"icon": "maki-art-gallery", "fields": ["name", "artist"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "mural"}, "reference": {"key": "artwork_type", "value": "mural"}, "terms": ["fresco", "wall painting"], "name": "Mural"},
|
||||
"tourism/artwork/sculpture": {"icon": "maki-art-gallery", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "sculpture"}, "reference": {"key": "artwork_type", "value": "sculpture"}, "terms": ["statue", "figure", "carving"], "name": "Sculpture"},
|
||||
"tourism/artwork/statue": {"icon": "maki-art-gallery", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "statue"}, "reference": {"key": "artwork_type", "value": "statue"}, "terms": ["sculpture", "figure", "carving"], "name": "Statue"},
|
||||
"tourism/artwork/statue": {"icon": "fas-female", "fields": ["name", "artist", "material"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "artwork", "artwork_type": "statue"}, "reference": {"key": "artwork_type", "value": "statue"}, "terms": ["sculpture", "figure", "carving"], "name": "Statue"},
|
||||
"tourism/attraction": {"icon": "maki-star", "fields": ["name", "operator", "address"], "geometry": ["point", "vertex", "line", "area"], "tags": {"tourism": "attraction"}, "matchScore": 0.75, "name": "Tourist Attraction"},
|
||||
"tourism/camp_site": {"icon": "maki-campsite", "fields": ["name", "operator", "address", "access_simple", "capacity", "fee", "payment_multi_fee", "internet_access", "internet_access/fee"], "moreFields": ["email", "fax", "internet_access/ssid", "phone", "power_supply", "reservation", "sanitary_dump_station", "website", "wheelchair"], "geometry": ["point", "vertex", "area"], "terms": ["tent", "rv"], "tags": {"tourism": "camp_site"}, "name": "Campground"},
|
||||
"tourism/caravan_site": {"icon": "temaki-rv_park", "fields": ["name", "address", "capacity", "sanitary_dump_station", "power_supply", "internet_access", "internet_access/fee"], "moreFields": ["operator", "fee", "payment_multi_fee", "internet_access/ssid", "smoking", "website", "phone", "email", "fax", "wheelchair", "reservation"], "geometry": ["point", "vertex", "area"], "terms": ["Motor Home", "Camper"], "tags": {"tourism": "caravan_site"}, "name": "RV Park"},
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
"tags": {
|
||||
"landuse": "meadow"
|
||||
},
|
||||
"terms": [],
|
||||
"terms": [
|
||||
"grazing",
|
||||
"hay field",
|
||||
"pasture"
|
||||
],
|
||||
"name": "Meadow"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"icon": "fas-user-alt",
|
||||
"fields": [
|
||||
"name",
|
||||
"artist",
|
||||
"material"
|
||||
],
|
||||
"geometry": [
|
||||
"point", "vertex"
|
||||
],
|
||||
"tags": {
|
||||
"tourism": "artwork",
|
||||
"artwork_type": "bust"
|
||||
},
|
||||
"reference": {
|
||||
"key": "artwork_type"
|
||||
},
|
||||
"terms": [
|
||||
"figure"
|
||||
],
|
||||
"name": "Bust"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"icon": "maki-art-gallery",
|
||||
"fields": [
|
||||
"name",
|
||||
"artist"
|
||||
],
|
||||
"geometry": [
|
||||
"point",
|
||||
"vertex",
|
||||
"line",
|
||||
"area"
|
||||
],
|
||||
"tags": {
|
||||
"tourism": "artwork",
|
||||
"artwork_type": "graffiti"
|
||||
},
|
||||
"reference": {
|
||||
"key": "artwork_type"
|
||||
},
|
||||
"terms": [
|
||||
"Street Artwork",
|
||||
"Guerilla Artwork",
|
||||
"Graffiti Artwork"
|
||||
],
|
||||
"name": "Graffiti"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"icon": "maki-art-gallery",
|
||||
"fields": [
|
||||
"name",
|
||||
"artist"
|
||||
],
|
||||
"geometry": [
|
||||
"point",
|
||||
"vertex",
|
||||
"line",
|
||||
"area"
|
||||
],
|
||||
"tags": {
|
||||
"tourism": "artwork",
|
||||
"artwork_type": "installation"
|
||||
},
|
||||
"reference": {
|
||||
"key": "artwork_type"
|
||||
},
|
||||
"terms": [
|
||||
"interactive art",
|
||||
"intervention art",
|
||||
"modern art"
|
||||
],
|
||||
"name": "Art Installation"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"icon": "maki-art-gallery",
|
||||
"icon": "fas-female",
|
||||
"fields": [
|
||||
"name",
|
||||
"artist",
|
||||
|
||||
+6
-1
@@ -1003,9 +1003,12 @@
|
||||
{"key": "tourism", "value": "apartment", "description": "🄿 Guest Apartment / Condo", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/lodging-15.svg?sanitize=true"},
|
||||
{"key": "tourism", "value": "aquarium", "description": "🄿 Aquarium", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/aquarium-15.svg?sanitize=true"},
|
||||
{"key": "tourism", "value": "artwork", "description": "🄿 Artwork", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"},
|
||||
{"key": "artwork_type", "value": "bust", "description": "🄿 Bust", "object_types": ["node"], "icon_url": "https://raw.githubusercontent.com/openstreetmap/iD/master/svg/fontawesome/fas-user-alt.svg?sanitize=true"},
|
||||
{"key": "artwork_type", "value": "graffiti", "description": "🄿 Graffiti", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"},
|
||||
{"key": "artwork_type", "value": "installation", "description": "🄿 Art Installation", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"},
|
||||
{"key": "artwork_type", "value": "mural", "description": "🄿 Mural", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"},
|
||||
{"key": "artwork_type", "value": "sculpture", "description": "🄿 Sculpture", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"},
|
||||
{"key": "artwork_type", "value": "statue", "description": "🄿 Statue", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/art-gallery-15.svg?sanitize=true"},
|
||||
{"key": "artwork_type", "value": "statue", "description": "🄿 Statue", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/openstreetmap/iD/master/svg/fontawesome/fas-female.svg?sanitize=true"},
|
||||
{"key": "tourism", "value": "attraction", "description": "🄿 Tourist Attraction", "object_types": ["node", "way", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/star-15.svg?sanitize=true"},
|
||||
{"key": "tourism", "value": "camp_site", "description": "🄿 Campground", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/mapbox/maki/master/icons/campsite-15.svg?sanitize=true"},
|
||||
{"key": "tourism", "value": "caravan_site", "description": "🄿 RV Park", "object_types": ["node", "area"], "icon_url": "https://raw.githubusercontent.com/bhousel/temaki/master/icons/rv_park.svg?sanitize=true"},
|
||||
@@ -1742,6 +1745,8 @@
|
||||
{"key": "amenity", "value": "winery", "description": "🄳 ➜ craft=winery"},
|
||||
{"key": "amenity", "value": "youth_center", "description": "🄳 ➜ amenity=community_centre + community_centre:for=juvenile"},
|
||||
{"key": "amenity", "value": "youth_centre", "description": "🄳 ➜ amenity=community_centre + community_centre:for=juvenile"},
|
||||
{"key": "artwork", "description": "🄳 ➜ artwork_type=*"},
|
||||
{"key": "artwork:type", "description": "🄳 ➜ artwork_type=*"},
|
||||
{"key": "barrier", "value": "curb", "description": "🄳 ➜ barrier=kerb"},
|
||||
{"key": "barrier", "value": "embankment", "description": "🄳 ➜ man_made=embankment"},
|
||||
{"key": "barrier", "value": "wire_fence", "description": "🄳 ➜ barrier=fence + fence_type=chain"},
|
||||
|
||||
Vendored
+13
-1
@@ -6451,7 +6451,7 @@
|
||||
},
|
||||
"landuse/meadow": {
|
||||
"name": "Meadow",
|
||||
"terms": ""
|
||||
"terms": "grazing,hay field,pasture"
|
||||
},
|
||||
"landuse/military": {
|
||||
"name": "Military Area",
|
||||
@@ -8525,6 +8525,18 @@
|
||||
"name": "Artwork",
|
||||
"terms": "mural,sculpture,statue"
|
||||
},
|
||||
"tourism/artwork/bust": {
|
||||
"name": "Bust",
|
||||
"terms": "figure"
|
||||
},
|
||||
"tourism/artwork/graffiti": {
|
||||
"name": "Graffiti",
|
||||
"terms": "Street Artwork,Guerilla Artwork,Graffiti Artwork"
|
||||
},
|
||||
"tourism/artwork/installation": {
|
||||
"name": "Art Installation",
|
||||
"terms": "interactive art,intervention art,modern art"
|
||||
},
|
||||
"tourism/artwork/mural": {
|
||||
"name": "Mural",
|
||||
"terms": "fresco,wall painting"
|
||||
|
||||
+47
-35
@@ -1,25 +1,21 @@
|
||||
import {
|
||||
event as d3_event,
|
||||
mouse as d3_mouse,
|
||||
select as d3_select
|
||||
} from 'd3-selection';
|
||||
import { event as d3_event, mouse as d3_mouse, select as d3_select } from 'd3-selection';
|
||||
|
||||
import { geoVecLength } from '../geo';
|
||||
|
||||
import { modeBrowse } from '../modes/browse';
|
||||
import { modeSelect } from '../modes/select';
|
||||
import { modeSelectData } from '../modes/select_data';
|
||||
import { modeSelectNote } from '../modes/select_note';
|
||||
import { modeSelectError } from '../modes/select_error';
|
||||
|
||||
import { osmEntity, osmNote, qaError } from '../osm';
|
||||
|
||||
|
||||
export function behaviorSelect(context) {
|
||||
var lastMouse = null;
|
||||
var suppressMenu = true;
|
||||
// legacy option to show menu on every click
|
||||
var isShowAlways = +context.storage('edit-menu-show-always') === 1;
|
||||
var tolerance = 4;
|
||||
var p1 = null;
|
||||
var _lastMouse = null;
|
||||
var _suppressMenu = true;
|
||||
var _p1 = null;
|
||||
|
||||
|
||||
function point() {
|
||||
@@ -58,17 +54,20 @@ export function behaviorSelect(context) {
|
||||
|
||||
|
||||
function mousedown() {
|
||||
if (!p1) p1 = point();
|
||||
if (!_p1) {
|
||||
_p1 = point();
|
||||
}
|
||||
d3_select(window)
|
||||
.on('mouseup.select', mouseup, true);
|
||||
|
||||
var isShowAlways = +context.storage('edit-menu-show-always') === 1;
|
||||
suppressMenu = !isShowAlways;
|
||||
_suppressMenu = !isShowAlways;
|
||||
}
|
||||
|
||||
|
||||
function mousemove() {
|
||||
if (d3_event) lastMouse = d3_event;
|
||||
if (d3_event) {
|
||||
_lastMouse = d3_event;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,15 +82,17 @@ export function behaviorSelect(context) {
|
||||
e.stopPropagation();
|
||||
|
||||
if (!+e.clientX && !+e.clientY) {
|
||||
if (lastMouse) {
|
||||
e.sourceEvent = lastMouse;
|
||||
if (_lastMouse) {
|
||||
e.sourceEvent = _lastMouse;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!p1) p1 = point();
|
||||
suppressMenu = false;
|
||||
if (!_p1) {
|
||||
_p1 = point();
|
||||
}
|
||||
_suppressMenu = false;
|
||||
click();
|
||||
}
|
||||
|
||||
@@ -100,18 +101,27 @@ export function behaviorSelect(context) {
|
||||
d3_select(window)
|
||||
.on('mouseup.select', null, true);
|
||||
|
||||
if (!p1) return;
|
||||
if (!_p1) return;
|
||||
var p2 = point();
|
||||
var dist = geoVecLength(p1, p2);
|
||||
|
||||
p1 = null;
|
||||
if (dist > tolerance) {
|
||||
return;
|
||||
}
|
||||
var dist = geoVecLength(_p1, p2);
|
||||
_p1 = null;
|
||||
if (dist > tolerance) return;
|
||||
|
||||
// Defer processing the click,
|
||||
// because this click may trigger a blur event,
|
||||
// and the blur event may trigger a tag change,
|
||||
// and we really want that tag change to go to the already selected entity
|
||||
// and not the one that we are about to select with the click #6028, #5878
|
||||
// (Be very careful entering modeSelect anywhere that might also blur a field!)
|
||||
var datum = d3_event.target.__data__ || (_lastMouse && _lastMouse.target.__data__);
|
||||
var isMultiselect = d3_event.shiftKey || d3_select('#surface .lasso').node();
|
||||
var isShowAlways = +context.storage('edit-menu-show-always') === 1;
|
||||
var datum = d3_event.target.__data__ || (lastMouse && lastMouse.target.__data__);
|
||||
window.setTimeout(function() {
|
||||
processClick(datum, isMultiselect);
|
||||
}, 20); // delay > whatever raw_tag_editor.js `scheduleChange` does (10ms).
|
||||
}
|
||||
|
||||
|
||||
function processClick(datum, isMultiselect) {
|
||||
var mode = context.mode();
|
||||
|
||||
var entity = datum && datum.properties && datum.properties.entity;
|
||||
@@ -127,18 +137,18 @@ export function behaviorSelect(context) {
|
||||
context.selectedErrorID(null);
|
||||
|
||||
if (!isMultiselect) {
|
||||
if (selectedIDs.length > 1 && (!suppressMenu && !isShowAlways)) {
|
||||
if (selectedIDs.length > 1 && (!_suppressMenu && !isShowAlways)) {
|
||||
// multiple things already selected, just show the menu...
|
||||
mode.suppressMenu(false).reselect();
|
||||
} else {
|
||||
// select a single thing..
|
||||
context.enter(modeSelect(context, [datum.id]).suppressMenu(suppressMenu));
|
||||
context.enter(modeSelect(context, [datum.id]).suppressMenu(_suppressMenu));
|
||||
}
|
||||
|
||||
} else {
|
||||
if (selectedIDs.indexOf(datum.id) !== -1) {
|
||||
// clicked entity is already in the selectedIDs list..
|
||||
if (!suppressMenu && !isShowAlways) {
|
||||
if (!_suppressMenu && !isShowAlways) {
|
||||
// don't deselect clicked entity, just show the menu.
|
||||
mode.suppressMenu(false).reselect();
|
||||
} else {
|
||||
@@ -149,7 +159,7 @@ export function behaviorSelect(context) {
|
||||
} else {
|
||||
// clicked entity is not in the selected list, add it..
|
||||
selectedIDs = selectedIDs.concat([datum.id]);
|
||||
context.enter(modeSelect(context, selectedIDs).suppressMenu(suppressMenu));
|
||||
context.enter(modeSelect(context, selectedIDs).suppressMenu(_suppressMenu));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,10 +172,12 @@ export function behaviorSelect(context) {
|
||||
context
|
||||
.selectedNoteID(datum.id)
|
||||
.enter(modeSelectNote(context, datum.id));
|
||||
|
||||
} else if (datum instanceof qaError & !isMultiselect) { // clicked an external QA error
|
||||
context
|
||||
.selectedErrorID(datum.id)
|
||||
.enter(modeSelectError(context, datum.id, datum.service));
|
||||
|
||||
} else { // clicked nothing..
|
||||
context.selectedNoteID(null);
|
||||
context.selectedErrorID(null);
|
||||
@@ -175,14 +187,14 @@ export function behaviorSelect(context) {
|
||||
}
|
||||
|
||||
// reset for next time..
|
||||
suppressMenu = true;
|
||||
_suppressMenu = true;
|
||||
}
|
||||
|
||||
|
||||
function behavior(selection) {
|
||||
lastMouse = null;
|
||||
suppressMenu = true;
|
||||
p1 = null;
|
||||
_lastMouse = null;
|
||||
_suppressMenu = true;
|
||||
_p1 = null;
|
||||
|
||||
d3_select(window)
|
||||
.on('keydown.select', keydown)
|
||||
|
||||
+24
-37
@@ -40,7 +40,6 @@ export function modeSelect(context, selectedIDs) {
|
||||
};
|
||||
|
||||
var keybinding = utilKeybinding('select');
|
||||
var timeout = null;
|
||||
var behaviors = [
|
||||
behaviorCopy(context),
|
||||
behaviorPaste(context),
|
||||
@@ -51,11 +50,12 @@ export function modeSelect(context, selectedIDs) {
|
||||
modeDragNode(context).restoreSelectedIDs(selectedIDs).behavior,
|
||||
modeDragNote(context).behavior
|
||||
];
|
||||
var inspector;
|
||||
var inspector; // unused?
|
||||
var editMenu;
|
||||
var newFeature = false;
|
||||
var suppressMenu = true;
|
||||
var follow = false;
|
||||
var _timeout = null;
|
||||
var _newFeature = false;
|
||||
var _suppressMenu = true;
|
||||
var _follow = false;
|
||||
|
||||
|
||||
var wrap = context.container()
|
||||
@@ -148,7 +148,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
var entity = singular();
|
||||
if (entity && context.geometry(entity.id) === 'relation') {
|
||||
suppressMenu = true;
|
||||
_suppressMenu = true;
|
||||
} else {
|
||||
var point = context.mouse();
|
||||
var viewport = geoExtent(context.projection.clipExtent()).polygon();
|
||||
@@ -156,7 +156,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
if (point && geoPointInPolygon(point, viewport)) {
|
||||
editMenu.center(point);
|
||||
} else {
|
||||
suppressMenu = true;
|
||||
_suppressMenu = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,29 +203,29 @@ export function modeSelect(context, selectedIDs) {
|
||||
}
|
||||
|
||||
positionMenu();
|
||||
if (!suppressMenu) {
|
||||
if (!_suppressMenu) {
|
||||
showMenu();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
mode.newFeature = function(val) {
|
||||
if (!arguments.length) return newFeature;
|
||||
newFeature = val;
|
||||
if (!arguments.length) return _newFeature;
|
||||
_newFeature = val;
|
||||
return mode;
|
||||
};
|
||||
|
||||
|
||||
mode.suppressMenu = function(val) {
|
||||
if (!arguments.length) return suppressMenu;
|
||||
suppressMenu = val;
|
||||
if (!arguments.length) return _suppressMenu;
|
||||
_suppressMenu = val;
|
||||
return mode;
|
||||
};
|
||||
|
||||
|
||||
mode.follow = function(val) {
|
||||
if (!arguments.length) return follow;
|
||||
follow = val;
|
||||
if (!arguments.length) return _follow;
|
||||
_follow = val;
|
||||
return mode;
|
||||
};
|
||||
|
||||
@@ -233,18 +233,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
mode.enter = function() {
|
||||
if (!checkSelectedIDs()) return;
|
||||
|
||||
var forceVisibleIDs = selectedIDs.slice();
|
||||
|
||||
selectedIDs.forEach(function(id) {
|
||||
var entity = context.entity(id);
|
||||
if (entity.type === 'relation') {
|
||||
forceVisibleIDs = forceVisibleIDs.concat(entity.members.map(function(member) {
|
||||
return member.id;
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
context.features().forceVisible(forceVisibleIDs);
|
||||
context.features().forceVisible(selectedIDs);
|
||||
|
||||
var operations = Object.values(Operations)
|
||||
.map(function(o) { return o(selectedIDs, context); })
|
||||
@@ -291,7 +280,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
: uiEditMenu(context, operations);
|
||||
|
||||
context.ui().sidebar
|
||||
.select(singular() ? singular().id : null, newFeature);
|
||||
.select(singular() ? singular().id : null, _newFeature);
|
||||
|
||||
context.history()
|
||||
.on('undone.select', update)
|
||||
@@ -312,7 +301,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
context.ui().sidebar.show(entities);
|
||||
}
|
||||
|
||||
if (follow) {
|
||||
if (_follow) {
|
||||
var extent = geoExtent();
|
||||
var graph = context.graph();
|
||||
selectedIDs.forEach(function(id) {
|
||||
@@ -326,9 +315,9 @@ export function modeSelect(context, selectedIDs) {
|
||||
context.map().pan([0,0]); // full redraw, to adjust z-sorting #2914
|
||||
}
|
||||
|
||||
timeout = window.setTimeout(function() {
|
||||
_timeout = window.setTimeout(function() {
|
||||
positionMenu();
|
||||
if (!suppressMenu) {
|
||||
if (!_suppressMenu) {
|
||||
showMenu();
|
||||
}
|
||||
}, 270); /* after any centerEase completes */
|
||||
@@ -378,7 +367,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
var entity = singular();
|
||||
|
||||
if (entity && context.geometry(entity.id) === 'relation') {
|
||||
suppressMenu = true;
|
||||
_suppressMenu = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -527,7 +516,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
|
||||
mode.exit = function() {
|
||||
if (timeout) window.clearTimeout(timeout);
|
||||
if (_timeout) window.clearTimeout(_timeout);
|
||||
if (inspector) wrap.call(inspector.close);
|
||||
|
||||
behaviors.forEach(context.uninstall);
|
||||
@@ -560,16 +549,14 @@ export function modeSelect(context, selectedIDs) {
|
||||
context.features().forceVisible([]);
|
||||
|
||||
var entity = singular();
|
||||
if (newFeature &&
|
||||
entity &&
|
||||
entity.type === 'relation' &&
|
||||
if (_newFeature && entity && entity.type === 'relation' &&
|
||||
// no tags
|
||||
Object.keys(entity.tags).length === 0 &&
|
||||
// no parent relations
|
||||
context.graph().parentRelations(entity).length === 0 &&
|
||||
// no members or one member with no role
|
||||
(entity.members.length === 0 || (entity.members.length === 1 && !entity.members[0].role))) {
|
||||
|
||||
(entity.members.length === 0 || (entity.members.length === 1 && !entity.members[0].role))
|
||||
) {
|
||||
// the user added this relation but didn't edit it at all, so just delete it
|
||||
var deleteAction = actionDeleteRelation(entity.id, true /* don't delete untagged members */);
|
||||
context.perform(deleteAction, t('operations.delete.annotation.relation'));
|
||||
|
||||
@@ -511,6 +511,13 @@ export function rendererFeatures(context) {
|
||||
_forceVisible = {};
|
||||
for (var i = 0; i < entityIDs.length; i++) {
|
||||
_forceVisible[entityIDs[i]] = true;
|
||||
var entity = context.hasEntity(entityIDs[i]);
|
||||
if (entity && entity.type === 'relation') {
|
||||
// also show relation members (one level deep)
|
||||
for (var j in entity.members) {
|
||||
_forceVisible[entity.members[j].id] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return features;
|
||||
};
|
||||
@@ -532,11 +539,14 @@ export function rendererFeatures(context) {
|
||||
|
||||
|
||||
// warm up the feature matching cache upon merging fetched data
|
||||
context.history().on('merge.features', function(entities) {
|
||||
context.history().on('merge.features', function(newEntities) {
|
||||
utilCallWhenIdle(function() {
|
||||
if (!entities) return;
|
||||
if (!newEntities) return;
|
||||
|
||||
var graph = context.graph();
|
||||
var types = utilArrayGroupBy(newEntities, 'type');
|
||||
// ensure that getMatches is called on relations before ways
|
||||
var entities = [].concat(types.relation || [], types.way || [], types.node || []);
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var geometry = entities[i].geometry(graph);
|
||||
features.getMatches(entities[i], graph, geometry);
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
|
||||
import {
|
||||
event as d3_event,
|
||||
select as d3_select
|
||||
} from 'd3-selection';
|
||||
import { event as d3_event, select as d3_select } from 'd3-selection';
|
||||
|
||||
import { t } from '../util/locale';
|
||||
import { services } from '../services';
|
||||
@@ -11,14 +7,14 @@ import { svgIcon } from '../svg/icon';
|
||||
import { uiCombobox } from './combobox';
|
||||
import { uiDisclosure } from './disclosure';
|
||||
import { uiTagReference } from './tag_reference';
|
||||
import { utilGetSetValue, utilNoAuto, utilRebind } from '../util';
|
||||
import { utilArrayDifference, utilGetSetValue, utilNoAuto, utilRebind } from '../util';
|
||||
|
||||
|
||||
export function uiRawTagEditor(context) {
|
||||
var taginfo = services.taginfo;
|
||||
var dispatch = d3_dispatch('change');
|
||||
var _readOnlyTags = [];
|
||||
var _orderedKeys = [];
|
||||
var _indexedKeys = [];
|
||||
var _showBlank = false;
|
||||
var _updatePreference = true;
|
||||
var _expanded = false;
|
||||
@@ -56,34 +52,27 @@ export function uiRawTagEditor(context) {
|
||||
|
||||
|
||||
function content(wrap) {
|
||||
var rowData = [];
|
||||
var seen = {};
|
||||
var allKeys = Object.keys(_tags);
|
||||
var i, k;
|
||||
|
||||
// When switching to a different entity or changing the state (hover/select)
|
||||
// we reorder the keys. Otherwise leave them as the user entered - #5857
|
||||
if (!_orderedKeys.length) {
|
||||
_orderedKeys = allKeys.sort();
|
||||
// reorder the keys alphabetically.
|
||||
// We trigger this by emptying the `_indexedKeys` array, then it will be rebuilt here.
|
||||
// Otherwise leave their order alone - #5857, #5927
|
||||
var all = Object.keys(_tags).sort();
|
||||
var known = _indexedKeys.map(function(t) { return t.key; });
|
||||
var missing = utilArrayDifference(all, known);
|
||||
for (var i = 0; i < missing.length; i++) {
|
||||
_indexedKeys.push({ index: _indexedKeys.length, key: missing[i] });
|
||||
}
|
||||
|
||||
// push ordered keys first
|
||||
for (i = 0; i < _orderedKeys.length; i++) {
|
||||
k = _orderedKeys[i];
|
||||
if (_tags[k] === undefined) continue; // e.g. tag was removed
|
||||
seen[k] = true;
|
||||
rowData.push({ key: k, value: _tags[k] });
|
||||
}
|
||||
// push unknown keys after - these are tags the user added
|
||||
for (i = 0; i < allKeys.length; i++) {
|
||||
k = allKeys[i];
|
||||
if (seen[k]) continue;
|
||||
rowData.push({ key: k, value: _tags[k] });
|
||||
}
|
||||
// push blank row last, if necessary
|
||||
if (!rowData.length || _showBlank) {
|
||||
// assemble row data, excluding any deleted tags
|
||||
var rowData = _indexedKeys.map(function(row) {
|
||||
var v = _tags[row.key];
|
||||
return (v === undefined) ? null : Object.assign(row, { value: v });
|
||||
}).filter(Boolean);
|
||||
|
||||
// append blank row last, if necessary
|
||||
if (!_indexedKeys.length || _showBlank) {
|
||||
_showBlank = false;
|
||||
rowData.push({ key: '', value: '' });
|
||||
rowData.push({ index: _indexedKeys.length, key: '', value: '' });
|
||||
}
|
||||
|
||||
// List of tags
|
||||
@@ -170,7 +159,7 @@ export function uiRawTagEditor(context) {
|
||||
// Update
|
||||
items = items
|
||||
.merge(itemsEnter)
|
||||
.order();
|
||||
.sort(function(a, b) { return a.index - b.index; });
|
||||
|
||||
items
|
||||
.each(function(d) {
|
||||
@@ -249,9 +238,7 @@ export function uiRawTagEditor(context) {
|
||||
query: value
|
||||
}, function(err, data) {
|
||||
if (!err) {
|
||||
var filtered = data.filter(function(d) {
|
||||
return _tags[d.value] === undefined;
|
||||
});
|
||||
var filtered = data.filter(function(d) { return _tags[d.value] === undefined; });
|
||||
callback(sort(value, filtered));
|
||||
}
|
||||
});
|
||||
@@ -355,7 +342,6 @@ export function uiRawTagEditor(context) {
|
||||
|
||||
this.value = kNew;
|
||||
utilGetSetValue(inputVal, vNew);
|
||||
|
||||
scheduleChange();
|
||||
}
|
||||
|
||||
@@ -408,7 +394,7 @@ export function uiRawTagEditor(context) {
|
||||
rawTagEditor.state = function(val) {
|
||||
if (!arguments.length) return _state;
|
||||
if (_state !== val) {
|
||||
_orderedKeys = [];
|
||||
_indexedKeys = [];
|
||||
_state = val;
|
||||
}
|
||||
return rawTagEditor;
|
||||
@@ -439,7 +425,7 @@ export function uiRawTagEditor(context) {
|
||||
rawTagEditor.entityID = function(val) {
|
||||
if (!arguments.length) return _entityID;
|
||||
if (_entityID !== val) {
|
||||
_orderedKeys = [];
|
||||
_indexedKeys = [];
|
||||
_entityID = val;
|
||||
}
|
||||
return rawTagEditor;
|
||||
@@ -454,6 +440,7 @@ export function uiRawTagEditor(context) {
|
||||
};
|
||||
|
||||
|
||||
// pass an array of regular expressions to test against the tag key
|
||||
rawTagEditor.readOnlyTags = function(val) {
|
||||
if (!arguments.length) return _readOnlyTags;
|
||||
_readOnlyTags = val;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="female" class="svg-inline--fa fa-female fa-w-8" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path fill="currentColor" d="M128 0c35.346 0 64 28.654 64 64s-28.654 64-64 64c-35.346 0-64-28.654-64-64S92.654 0 128 0m119.283 354.179l-48-192A24 24 0 0 0 176 144h-11.36c-22.711 10.443-49.59 10.894-73.28 0H80a24 24 0 0 0-23.283 18.179l-48 192C4.935 369.305 16.383 384 32 384h56v104c0 13.255 10.745 24 24 24h32c13.255 0 24-10.745 24-24V384h56c15.591 0 27.071-14.671 23.283-29.821z"></path></svg>
|
||||
|
After Width: | Height: | Size: 581 B |
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="user-alt" class="svg-inline--fa fa-user-alt fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 288c79.5 0 144-64.5 144-144S335.5 0 256 0 112 64.5 112 144s64.5 144 144 144zm128 32h-55.1c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16H128C57.3 320 0 377.3 0 448v16c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-16c0-70.7-57.3-128-128-128z"></path></svg>
|
||||
|
After Width: | Height: | Size: 480 B |
@@ -43,50 +43,68 @@ describe('iD.behaviorSelect', function() {
|
||||
expect(context.mode().id).to.eql('browse');
|
||||
});
|
||||
|
||||
specify('click on entity selects the entity', function() {
|
||||
specify('click on entity selects the entity', function(done) {
|
||||
var el = context.surface().selectAll('.' + a.id).node();
|
||||
happen.mousedown(el);
|
||||
happen.mouseup(el);
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
window.setTimeout(function() {
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
specify('click on empty space clears the selection', function() {
|
||||
specify('click on empty space clears the selection', function(done) {
|
||||
context.enter(iD.modeSelect(context, [a.id]));
|
||||
var el = context.surface().node();
|
||||
happen.mousedown(el);
|
||||
happen.mouseup(el);
|
||||
expect(context.mode().id).to.eql('browse');
|
||||
window.setTimeout(function() {
|
||||
expect(context.mode().id).to.eql('browse');
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
specify('shift-click on unselected entity adds it to the selection', function() {
|
||||
specify('shift-click on unselected entity adds it to the selection', function(done) {
|
||||
context.enter(iD.modeSelect(context, [a.id]));
|
||||
var el = context.surface().selectAll('.' + b.id).node();
|
||||
happen.mousedown(el, { shiftKey: true });
|
||||
happen.mouseup(el, { shiftKey: true });
|
||||
expect(context.selectedIDs()).to.eql([a.id, b.id]);
|
||||
window.setTimeout(function() {
|
||||
expect(context.selectedIDs()).to.eql([a.id, b.id]);
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
specify('shift-click on selected entity removes it from the selection', function() {
|
||||
specify('shift-click on selected entity removes it from the selection', function(done) {
|
||||
context.enter(iD.modeSelect(context, [a.id, b.id]));
|
||||
var el = context.surface().selectAll('.' + b.id).node();
|
||||
happen.mousedown(el, { shiftKey: true });
|
||||
happen.mouseup(el, { shiftKey: true });
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
window.setTimeout(function() {
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
specify('shift-click on last selected entity clears the selection', function() {
|
||||
specify('shift-click on last selected entity clears the selection', function(done) {
|
||||
context.enter(iD.modeSelect(context, [a.id]));
|
||||
var el = context.surface().selectAll('.' + a.id).node();
|
||||
happen.mousedown(el, { shiftKey: true });
|
||||
happen.mouseup(el, { shiftKey: true });
|
||||
expect(context.mode().id).to.eql('browse');
|
||||
window.setTimeout(function() {
|
||||
expect(context.mode().id).to.eql('browse');
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
|
||||
specify('shift-click on empty space leaves the selection unchanged', function() {
|
||||
specify('shift-click on empty space leaves the selection unchanged', function(done) {
|
||||
context.enter(iD.modeSelect(context, [a.id]));
|
||||
var el = context.surface().node();
|
||||
happen.mousedown(el, { shiftKey: true });
|
||||
happen.mouseup(el, { shiftKey: true });
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
window.setTimeout(function() {
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
done();
|
||||
}, 50);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user