mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-02 00:15:12 +02:00
Merge branch 'develop' into accessible_ui
This commit is contained in:
@@ -6,3 +6,9 @@ contact_links:
|
||||
- name: There is an issue with brand icons or brand tagging recommendations.
|
||||
url: https://github.com/osmlab/name-suggestion-index/issues
|
||||
about: Please create a feature request in the name-suggestion-index repository.
|
||||
- name: There is an issue with a background imagery source.
|
||||
url: https://github.com/osmlab/editor-layer-index/issues
|
||||
about: Please create an issue in the editor-layer-index repository.
|
||||
- name: You have a general question or want to discuss something.
|
||||
url: https://github.community/
|
||||
about: Please ask and answer questions in iD's Discussions tab.
|
||||
|
||||
@@ -262,7 +262,7 @@ iD's preset database is stored in the `iD.fileFetcher.cache().presets` object an
|
||||
or modified prior to creating the iD context.
|
||||
|
||||
The format of the `presets` object is
|
||||
[documented here](https://github.com/openstreetmap/iD/tree/develop/data/presets#custom-presets).
|
||||
[documented as part of the schema-builder project](https://github.com/ideditor/schema-builder#presets).
|
||||
|
||||
To add a new preset to iD's existing preset database.
|
||||
```js
|
||||
|
||||
@@ -14,6 +14,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
|
||||
##### YYYY-MMM-DD
|
||||
|
||||
#### :newspaper: News
|
||||
#### :shield: Security
|
||||
#### :mega: Release Highlights
|
||||
#### :boom: Breaking Changes
|
||||
#### :tada: New Features
|
||||
@@ -41,10 +42,16 @@ _Breaking developer changes, which may affect downstream projects or sites that
|
||||
|
||||
#### :newspaper: News
|
||||
* We maintain a running changelog now! Upcoming changes will be added to the _[Unreleased](#Unreleased)_ section of this changelog as soon as they are ready in the [development version](https://ideditor.netlify.app/) of the iD editor. ([#8805])
|
||||
#### :shield: Security
|
||||
* Fix missing escaping of external texts and content such as OSM user names, OSM tags, etc. which had opened a way to inject arbitrary HTML into the iD editor, potentially making XSS attacks possible. ([#8813])
|
||||
#### :boom: Breaking Changes
|
||||
#### :tada: New Features
|
||||
#### :sparkles: Usability & Accessibility
|
||||
* Add a preview to colour fields, showing a native colour picker dialog on click ([#8782], thanks [@k-yle])
|
||||
* Tag keys of a multi-selection can now also be changed in the tags editor when the tag values differ in the selected features. ([#8836])
|
||||
#### :scissors: Operations
|
||||
* Split operation now indicates more clearly when multiple ways will be affected and gives a hint how to restrict the operation to a single line ([#8818])
|
||||
* Many operations now better preserve OSM object history ([#8839], thanks [@tpetillon])
|
||||
#### :camera: Street-Level
|
||||
* Rename OpenStreetCam overlay to KartaView ([#8807])
|
||||
#### :white_check_mark: Validation
|
||||
@@ -53,24 +60,42 @@ _Breaking developer changes, which may affect downstream projects or sites that
|
||||
#### :bug: Bugfixes
|
||||
* Fix hidden tooltips on map control toolbar ([#8781])
|
||||
* Fix glitching out turn restriction minimap on narrow sidebars ([#8792])
|
||||
* Fix non-string properties of GeoJSON custom map data not being displayed correctly ([#8825], thanks [@k-yle])
|
||||
* Fix a bug which made it impossible to switch to a custom TMS imagery layer after using a custom WMS source and vice versa ([#8057])
|
||||
* Fix a bug where the validator might show wrong tagging suggestions for a preset if another preset has a partial match ([#8828], thanks [@bhousel])
|
||||
* Show correct vintage and other metadata for "Esri World Imagery"'s higher zoom levels
|
||||
* Fix wrong order of route relation members after a split operation ([#8519], thanks [@tpetillon])
|
||||
#### :earth_asia: Localization
|
||||
* Deprecate ~`t.html`~ for providing localized texts, which is replaced by the new method `t.append` which directly and safely appends the localized strings to the DOM ([#8817])
|
||||
#### :hourglass: Performance
|
||||
#### :mortar_board: Walkthrough / Help
|
||||
* Show privacy settings in splash screen (i.e. the "Welcome to iD" message) ([#8831])
|
||||
#### :rocket: Presets
|
||||
* Radio-button based presets fields can be in an non-unique state (e.g. a tunnel which is also a ford) – this is now rendered like a multi selection with conflicting states ([#8796])
|
||||
* Add colours for preset categories ([#8799])
|
||||
#### :hammer: Development
|
||||
|
||||
[#8057]: https://github.com/openstreetmap/iD/issues/8057
|
||||
[#8519]: https://github.com/openstreetmap/iD/issues/8519
|
||||
[#8771]: https://github.com/openstreetmap/iD/issues/8771
|
||||
[#8781]: https://github.com/openstreetmap/iD/issues/8781
|
||||
[#8782]: https://github.com/openstreetmap/iD/pull/8782
|
||||
[#8792]: https://github.com/openstreetmap/iD/pull/8792
|
||||
[#8796]: https://github.com/openstreetmap/iD/issues/8796
|
||||
[#8799]: https://github.com/openstreetmap/iD/issues/8799
|
||||
[#8800]: https://github.com/openstreetmap/iD/pull/8800
|
||||
[#8805]: https://github.com/openstreetmap/iD/issues/8805
|
||||
[#8807]: https://github.com/openstreetmap/iD/issues/8807
|
||||
[#8813]: https://github.com/openstreetmap/iD/issues/8813
|
||||
[#8817]: https://github.com/openstreetmap/iD/pull/8817
|
||||
[#8818]: https://github.com/openstreetmap/iD/issues/8818
|
||||
[#8825]: https://github.com/openstreetmap/iD/pull/8825
|
||||
[#8828]: https://github.com/openstreetmap/iD/pull/8828
|
||||
[#8831]: https://github.com/openstreetmap/iD/issues/8831
|
||||
[#8836]: https://github.com/openstreetmap/iD/issues/8836
|
||||
[#8839]: https://github.com/openstreetmap/iD/pull/8839
|
||||
[@k-yle]: https://github.com/k-yle
|
||||
[@tpetillon]: https://github.com/tpetillon
|
||||
|
||||
# 2.20.2
|
||||
##### 2021-Oct-28
|
||||
|
||||
+50
-7
@@ -194,7 +194,8 @@ input[type=number],
|
||||
input[type=url],
|
||||
input[type=tel],
|
||||
input[type=email],
|
||||
input[type=date] {
|
||||
input[type=date],
|
||||
input[type=color] {
|
||||
/* need this since line-height interpretation may vary by font or browser */
|
||||
height: 2.585em;
|
||||
}
|
||||
@@ -1510,6 +1511,34 @@ a.hide-toggle {
|
||||
fill: #333;
|
||||
opacity: .5;
|
||||
}
|
||||
.form-field-button.colour-preview {
|
||||
border-radius: 0 0 4px 0;
|
||||
}
|
||||
.form-field-button.colour-preview > div.colour-box {
|
||||
border: 3px solid #fff;
|
||||
height: 100%;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
padding: 1px 0 0 1px;
|
||||
}
|
||||
.inspector-hover .form-field-button.colour-preview > div.colour-box {
|
||||
border-color: #ececec;
|
||||
}
|
||||
.form-field-button.colour-preview:active > div.colour-box,
|
||||
.form-field-button.colour-preview:focus > div.colour-box {
|
||||
border-color: #f1f1f1;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.form-field-button.colour-preview:hover > div.colour-box {
|
||||
border-color: #f1f1f1;
|
||||
}
|
||||
}
|
||||
.form-field-button.colour-selector {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* round corners of first/last child elements */
|
||||
@@ -1708,12 +1737,13 @@ a.hide-toggle {
|
||||
|
||||
/* Field - Text / Numeric
|
||||
------------------------------------------------------- */
|
||||
.form-field-input-text > input:only-of-type,
|
||||
.form-field-input-text > input:only-child,
|
||||
.form-field-input-tel > input:only-of-type,
|
||||
.form-field-input-email > input:only-of-type,
|
||||
.form-field-input-url > input:only-child {
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
.form-field-input-text > input:not(:only-child),
|
||||
.form-field-input-url > input:not(:only-child) {
|
||||
border-radius: 0 0 0 4px;
|
||||
}
|
||||
@@ -4941,6 +4971,14 @@ img.tile-debug {
|
||||
color: #7092ff;
|
||||
}
|
||||
|
||||
.modal-splash .section-preferences-third-party {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.modal-splash .section-preferences-third-party .privacy-link {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* Shortcuts Modal
|
||||
------------------------------------------------------- */
|
||||
@@ -5353,22 +5391,26 @@ button.conflicts-button {
|
||||
/* dark tooltips for sidebar / panels */
|
||||
.tooltip.dark.top .popover-arrow,
|
||||
.map-pane .tooltip.top .popover-arrow,
|
||||
.sidebar .tooltip.top .popover-arrow {
|
||||
.sidebar .tooltip.top .popover-arrow,
|
||||
.modal .tooltip.top .popover-arrow {
|
||||
border-top-color: #000;
|
||||
}
|
||||
.tooltip.dark.bottom .popover-arrow,
|
||||
.map-pane .tooltip.bottom .popover-arrow,
|
||||
.sidebar .tooltip.bottom .popover-arrow {
|
||||
.sidebar .tooltip.bottom .popover-arrow,
|
||||
.modal .tooltip.bottom .popover-arrow {
|
||||
border-bottom-color: #000;
|
||||
}
|
||||
.tooltip.dark.left .popover-arrow,
|
||||
.map-pane .tooltip.left .popover-arrow,
|
||||
.sidebar .tooltip.left .popover-arrow {
|
||||
.sidebar .tooltip.left .popover-arrow,
|
||||
.modal .tooltip.left .popover-arrow {
|
||||
border-left-color: #000;
|
||||
}
|
||||
.tooltip.dark.right .popover-arrow,
|
||||
.map-pane .tooltip.right .popover-arrow,
|
||||
.sidebar .tooltip.right .popover-arrow {
|
||||
.sidebar .tooltip.right .popover-arrow,
|
||||
.modal .tooltip.right .popover-arrow {
|
||||
border-right-color: #000;
|
||||
}
|
||||
.tooltip.dark .popover-inner,
|
||||
@@ -5379,7 +5421,8 @@ button.conflicts-button {
|
||||
.map-pane .keyhint-wrap,
|
||||
.sidebar .popover-inner,
|
||||
.sidebar .tooltip-heading,
|
||||
.sidebar .keyhint-wrap {
|
||||
.sidebar .keyhint-wrap,
|
||||
.modal .popover-inner {
|
||||
background: #000;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
+7
-4
@@ -474,8 +474,8 @@ en:
|
||||
single_node: Divide this line into two at this point.
|
||||
multiple_node: Divide this line at these points.
|
||||
multiple:
|
||||
single_node: Divide these lines at this point.
|
||||
multiple_node: Divide these lines at these points.
|
||||
single_node: "Divide all lines at this point. Tip: To limit this operation to a specific line, select both the line and point before performing the split."
|
||||
multiple_node: "Divide all lines at these points. Tip: To limit this operation to a specific line, select the line as well as the points before performing the split."
|
||||
area:
|
||||
single:
|
||||
single_node: Divide the edge of this area into two at this point.
|
||||
@@ -649,8 +649,10 @@ en:
|
||||
last_edit: Last Edit
|
||||
edited_by: Edited By
|
||||
changeset: Changeset
|
||||
changeset_link: Changeset on osm.org
|
||||
profile_link: Profile on osm.org
|
||||
history_link: History on osm.org
|
||||
unknown: Unknown
|
||||
link_text: History on openstreetmap.org
|
||||
note_no_history: "No History (New Note)"
|
||||
note_comments: Comments
|
||||
note_created_date: Created Date
|
||||
@@ -1010,7 +1012,7 @@ en:
|
||||
location: 'This feature was moved by both you and {user}.'
|
||||
nodelist: 'Nodes were changed by both you and {user}.'
|
||||
memberlist: 'Relation members were changed by both you and {user}.'
|
||||
tags: 'You changed the <b>{tag}</b> tag to "{local}" and {user} changed it to "{remote}".'
|
||||
tags: 'You changed the "{tag}" tag to "{local}" and {user} changed it to "{remote}".'
|
||||
success:
|
||||
just_edited: "You just edited OpenStreetMap!"
|
||||
thank_you: "Thank you for improving the map."
|
||||
@@ -1038,6 +1040,7 @@ en:
|
||||
privacy_update: "Our privacy policy has recently been updated."
|
||||
privacy_policy: iD privacy policy
|
||||
privacy: "{updateMessage} By using this software, you agree to do so in accordance with the {privacyLink}."
|
||||
privacy_settings: Your Privacy Settings
|
||||
walkthrough: "Start the Walkthrough"
|
||||
start: "Edit now"
|
||||
source_switch:
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -32,7 +32,7 @@ export function actionAddMember(relationId, member, memberIndex, insertPair) {
|
||||
// Add a way member into the relation "wherever it makes sense".
|
||||
// In this situation we were not supplied a memberIndex.
|
||||
function addWayMember(relation, graph) {
|
||||
var groups, tempWay, item, i, j, k;
|
||||
var groups, tempWay, insertPairIsReversed, item, i, j, k;
|
||||
|
||||
// remove PTv2 stops and platforms before doing anything.
|
||||
var PTv2members = [];
|
||||
@@ -65,6 +65,14 @@ export function actionAddMember(relationId, member, memberIndex, insertPair) {
|
||||
groups = utilArrayGroupBy(tempRelation.members, 'type');
|
||||
groups.way = groups.way || [];
|
||||
|
||||
// Insert pair is reversed if the inserted way comes before the original one.
|
||||
// (Except when they form a loop.)
|
||||
var originalWay = graph.entity(insertPair.originalID);
|
||||
var insertedWay = graph.entity(insertPair.insertedID);
|
||||
insertPairIsReversed = originalWay.nodes.length > 0 && insertedWay.nodes.length > 0 &&
|
||||
insertedWay.nodes[insertedWay.nodes.length - 1] === originalWay.nodes[0] &&
|
||||
originalWay.nodes[originalWay.nodes.length - 1] !== insertedWay.nodes[0];
|
||||
|
||||
} else {
|
||||
// Add the member anywhere, one time. Just push and let `osmJoinWays` decide where to put it.
|
||||
groups = utilArrayGroupBy(relation.members, 'type');
|
||||
@@ -96,16 +104,17 @@ export function actionAddMember(relationId, member, memberIndex, insertPair) {
|
||||
|
||||
// If this is a paired item, generate members in correct order and role
|
||||
if (tempWay && item.id === tempWay.id) {
|
||||
if (nodes[0].id === insertPair.nodes[0]) {
|
||||
item.pair = [
|
||||
{ id: insertPair.originalID, type: 'way', role: item.role },
|
||||
{ id: insertPair.insertedID, type: 'way', role: item.role }
|
||||
];
|
||||
} else {
|
||||
var reverse = nodes[0].id !== insertPair.nodes[0] ^ insertPairIsReversed;
|
||||
if (reverse) {
|
||||
item.pair = [
|
||||
{ id: insertPair.insertedID, type: 'way', role: item.role },
|
||||
{ id: insertPair.originalID, type: 'way', role: item.role }
|
||||
];
|
||||
} else {
|
||||
item.pair = [
|
||||
{ id: insertPair.originalID, type: 'way', role: item.role },
|
||||
{ id: insertPair.insertedID, type: 'way', role: item.role }
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-10
@@ -1,12 +1,12 @@
|
||||
import { actionDeleteNode } from './delete_node';
|
||||
import { actionDeleteWay } from './delete_way';
|
||||
import { utilArrayUniq } from '../util';
|
||||
import { utilArrayUniq, utilOldestID } from '../util';
|
||||
|
||||
|
||||
// Connect the ways at the given nodes.
|
||||
//
|
||||
// First choose a node to be the survivor, with preference given
|
||||
// to an existing (not new) node.
|
||||
// to the oldest existing (not new) and "interesting" node.
|
||||
//
|
||||
// Tags and relation memberships of of non-surviving nodes are merged
|
||||
// to the survivor.
|
||||
@@ -24,11 +24,21 @@ export function actionConnect(nodeIDs) {
|
||||
var parents;
|
||||
var i, j;
|
||||
|
||||
// Choose a survivor node, prefer an existing (not new) node - #4974
|
||||
// Select the node with the ID passed as parameter if it is in the list,
|
||||
// otherwise select the node with the oldest ID as the survivor, or the
|
||||
// last one if there are only new nodes.
|
||||
nodeIDs.reverse();
|
||||
|
||||
var interestingIDs = [];
|
||||
for (i = 0; i < nodeIDs.length; i++) {
|
||||
survivor = graph.entity(nodeIDs[i]);
|
||||
if (survivor.version) break; // found one
|
||||
node = graph.entity(nodeIDs[i]);
|
||||
if (node.hasInterestingTags()) {
|
||||
if (!node.isNew()) {
|
||||
interestingIDs.push(node.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
survivor = graph.entity(utilOldestID(interestingIDs.length > 0 ? interestingIDs : nodeIDs));
|
||||
|
||||
// Replace all non-surviving nodes with the survivor and merge tags.
|
||||
for (i = 0; i < nodeIDs.length; i++) {
|
||||
@@ -71,11 +81,8 @@ export function actionConnect(nodeIDs) {
|
||||
var relations, relation, role;
|
||||
var i, j, k;
|
||||
|
||||
// Choose a survivor node, prefer an existing (not new) node - #4974
|
||||
for (i = 0; i < nodeIDs.length; i++) {
|
||||
survivor = graph.entity(nodeIDs[i]);
|
||||
if (survivor.version) break; // found one
|
||||
}
|
||||
// Select the node with the oldest ID as the survivor.
|
||||
survivor = graph.entity(utilOldestID(nodeIDs));
|
||||
|
||||
// 1. disable if the nodes being connected have conflicting relation roles
|
||||
for (i = 0; i < nodeIDs.length; i++) {
|
||||
|
||||
+6
-12
@@ -3,7 +3,7 @@ import { actionDeleteWay } from './delete_way';
|
||||
import { osmIsInterestingTag } from '../osm/tags';
|
||||
import { osmJoinWays } from '../osm/multipolygon';
|
||||
import { geoPathIntersections } from '../geo';
|
||||
import { utilArrayGroupBy, utilArrayIdentical, utilArrayIntersection } from '../util';
|
||||
import { utilArrayGroupBy, utilArrayIdentical, utilArrayIntersection, utilOldestID } from '../util';
|
||||
|
||||
|
||||
// Join ways at the end node they share.
|
||||
@@ -28,6 +28,11 @@ export function actionJoin(ids) {
|
||||
var action = function(graph) {
|
||||
var ways = ids.map(graph.entity, graph);
|
||||
|
||||
// Prefer to keep an existing way.
|
||||
// if there are multiple existing ways, keep the oldest one
|
||||
// the oldest way is determined by the ID of the way.
|
||||
var survivorID = utilOldestID(ways.map(way => way.id));
|
||||
|
||||
// if any of the ways are sided (e.g. coastline, cliff, kerb)
|
||||
// sort them first so they establish the overall order - #6033
|
||||
ways.sort(function(a, b) {
|
||||
@@ -38,17 +43,6 @@ export function actionJoin(ids) {
|
||||
: 0;
|
||||
});
|
||||
|
||||
// Prefer to keep an existing way.
|
||||
// if there are multiple existing ways, keep the oldest one
|
||||
// the oldest way is determined by the ID of the way
|
||||
const survivorID = (
|
||||
ways
|
||||
.filter((way) => !way.isNew())
|
||||
.sort((a, b) => +a.osmId() - +b.osmId())[0] || ways[0]
|
||||
).id;
|
||||
|
||||
|
||||
|
||||
var sequences = osmJoinWays(ways, graph);
|
||||
var joined = sequences[0];
|
||||
|
||||
|
||||
+58
-14
@@ -1,5 +1,5 @@
|
||||
import { osmTagSuggestingArea } from '../osm/tags';
|
||||
import { utilArrayGroupBy, utilArrayUniq } from '../util';
|
||||
import { utilArrayGroupBy, utilArrayUniq, utilCompareIDs } from '../util';
|
||||
|
||||
|
||||
export function actionMerge(ids) {
|
||||
@@ -29,21 +29,65 @@ export function actionMerge(ids) {
|
||||
var nodes = utilArrayUniq(graph.childNodes(target));
|
||||
var removeNode = point;
|
||||
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
var node = nodes[i];
|
||||
if (graph.parentWays(node).length > 1 ||
|
||||
graph.parentRelations(node).length ||
|
||||
node.hasInterestingTags()) {
|
||||
continue;
|
||||
if (!point.isNew()) {
|
||||
// Try to preserve the original point if it already has
|
||||
// an ID in the database.
|
||||
|
||||
var inserted = false;
|
||||
|
||||
var canBeReplaced = function(node) {
|
||||
return !(graph.parentWays(node).length > 1 ||
|
||||
graph.parentRelations(node).length);
|
||||
};
|
||||
|
||||
var replaceNode = function(node) {
|
||||
graph = graph.replace(point.update({ tags: node.tags, loc: node.loc }));
|
||||
target = target.replaceNode(node.id, point.id);
|
||||
graph = graph.replace(target);
|
||||
removeNode = node;
|
||||
inserted = true;
|
||||
};
|
||||
|
||||
var i;
|
||||
var node;
|
||||
|
||||
// First, try to replace a new child node on the target way.
|
||||
for (i = 0; i < nodes.length; i++) {
|
||||
node = nodes[i];
|
||||
if (canBeReplaced(node) && node.isNew()) {
|
||||
replaceNode(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Found an uninteresting child node on the target way.
|
||||
// Move orig point into its place to preserve point's history. #3683
|
||||
graph = graph.replace(point.update({ tags: {}, loc: node.loc }));
|
||||
target = target.replaceNode(node.id, point.id);
|
||||
graph = graph.replace(target);
|
||||
removeNode = node;
|
||||
break;
|
||||
if (!inserted && point.hasInterestingTags()) {
|
||||
// No new child node found, try to find an existing, but
|
||||
// uninteresting child node instead.
|
||||
for (i = 0; i < nodes.length; i++) {
|
||||
node = nodes[i];
|
||||
if (canBeReplaced(node) &&
|
||||
!node.hasInterestingTags()) {
|
||||
replaceNode(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inserted) {
|
||||
// Still not inserted, try to find an existing, interesting,
|
||||
// but more recent child node.
|
||||
for (i = 0; i < nodes.length; i++) {
|
||||
node = nodes[i];
|
||||
if (canBeReplaced(node) &&
|
||||
utilCompareIDs(point.id, node.id) < 0) {
|
||||
replaceNode(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the point still hasn't been inserted, we give up.
|
||||
// There are more interesting or older nodes on the way.
|
||||
}
|
||||
}
|
||||
|
||||
graph = graph.remove(removeNode);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { geoPolygonContainsPolygon } from '../geo';
|
||||
import { osmJoinWays, osmRelation } from '../osm';
|
||||
import { utilArrayGroupBy, utilArrayIntersection, utilObjectOmit } from '../util';
|
||||
import { utilArrayGroupBy, utilArrayIntersection, utilObjectOmit, utilOldestID } from '../util';
|
||||
|
||||
|
||||
export function actionMergePolygon(ids, newRelationId) {
|
||||
@@ -85,13 +85,21 @@ export function actionMergePolygon(ids, newRelationId) {
|
||||
outer = !outer;
|
||||
}
|
||||
|
||||
// Move all tags to one relation
|
||||
var relation = entities.multipolygon[0] ||
|
||||
osmRelation({ id: newRelationId, tags: { type: 'multipolygon' }});
|
||||
// Move all tags to one relation.
|
||||
// Keep the oldest multipolygon alive if it exists.
|
||||
var relation;
|
||||
if (entities.multipolygon.length > 0) {
|
||||
var oldestID = utilOldestID(entities.multipolygon.map((entity) => entity.id));
|
||||
relation = entities.multipolygon.find((entity) => entity.id === oldestID);
|
||||
} else {
|
||||
relation = osmRelation({ id: newRelationId, tags: { type: 'multipolygon' }});
|
||||
}
|
||||
|
||||
entities.multipolygon.slice(1).forEach(function(m) {
|
||||
relation = relation.mergeTags(m.tags);
|
||||
graph = graph.remove(m);
|
||||
entities.multipolygon.forEach(function(m) {
|
||||
if (m.id !== relation.id) {
|
||||
relation = relation.mergeTags(m.tags);
|
||||
graph = graph.remove(m);
|
||||
}
|
||||
});
|
||||
|
||||
entities.closedWay.forEach(function(way) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import { diff3Merge } from 'node-diff3';
|
||||
import { escape } from 'lodash';
|
||||
|
||||
import { t } from '../core/localizer';
|
||||
import { actionDeleteMultiple } from './delete_multiple';
|
||||
@@ -14,7 +15,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, discardTag
|
||||
|
||||
|
||||
function user(d) {
|
||||
return (typeof formatUser === 'function') ? formatUser(d) : d;
|
||||
return (typeof formatUser === 'function') ? formatUser(d) : escape(d);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +32,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, discardTag
|
||||
return target.update({loc: remote.loc});
|
||||
}
|
||||
|
||||
_conflicts.push(t('merge_remote_changes.conflict.location', { user: user(remote.user) }));
|
||||
_conflicts.push(t.html('merge_remote_changes.conflict.location', { user: { html: user(remote.user) } }));
|
||||
return target;
|
||||
}
|
||||
|
||||
@@ -64,7 +65,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, discardTag
|
||||
} else if (deepEqual(c.o, c.b)) { // only changed locally
|
||||
nodes.push.apply(nodes, c.a);
|
||||
} else { // changed both locally and remotely
|
||||
_conflicts.push(t('merge_remote_changes.conflict.nodelist', { user: user(remote.user) }));
|
||||
_conflicts.push(t.html('merge_remote_changes.conflict.nodelist', { user: { html: user(remote.user) } }));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -118,7 +119,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, discardTag
|
||||
if (remote.visible) {
|
||||
target = mergeLocation(remote, target);
|
||||
} else {
|
||||
_conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
|
||||
_conflicts.push(t.html('merge_remote_changes.conflict.deleted', { user: { html: user(remote.user) } }));
|
||||
}
|
||||
|
||||
if (_conflicts.length !== ccount) break;
|
||||
@@ -149,7 +150,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, discardTag
|
||||
return target.update({members: remote.members});
|
||||
}
|
||||
|
||||
_conflicts.push(t('merge_remote_changes.conflict.memberlist', { user: user(remote.user) }));
|
||||
_conflicts.push(t.html('merge_remote_changes.conflict.memberlist', { user: { html: user(remote.user) } }));
|
||||
return target;
|
||||
}
|
||||
|
||||
@@ -176,9 +177,8 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, discardTag
|
||||
|
||||
if (o[k] !== b[k] && a[k] !== b[k]) { // changed remotely..
|
||||
if (o[k] !== a[k]) { // changed locally..
|
||||
_conflicts.push(t('merge_remote_changes.conflict.tags',
|
||||
{ tag: k, local: a[k], remote: b[k], user: user(remote.user) }));
|
||||
|
||||
_conflicts.push(t.html('merge_remote_changes.conflict.tags',
|
||||
{ tag: k, local: a[k], remote: b[k], user: { html: user(remote.user) } }));
|
||||
} else { // unchanged locally, accept remote change..
|
||||
if (b.hasOwnProperty(k)) {
|
||||
tags[k] = b[k];
|
||||
@@ -224,7 +224,7 @@ export function actionMergeRemoteChanges(id, localGraph, remoteGraph, discardTag
|
||||
return graph.replace(target);
|
||||
|
||||
} else {
|
||||
_conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
|
||||
_conflicts.push(t.html('merge_remote_changes.conflict.deleted', { user: { html: user(remote.user) } }));
|
||||
return graph; // do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,7 +447,7 @@ export function behaviorDrawWay(context, wayID, mode, startGraph) {
|
||||
context.ui().flash
|
||||
.duration(4000)
|
||||
.iconName('#iD-icon-no')
|
||||
.label(t('operations.follow.error.needs_more_initial_nodes'))();
|
||||
.label(t.html('operations.follow.error.needs_more_initial_nodes'))();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -461,7 +461,7 @@ export function behaviorDrawWay(context, wayID, mode, startGraph) {
|
||||
context.ui().flash
|
||||
.duration(4000)
|
||||
.iconName('#iD-icon-no')
|
||||
.label(t(`operations.follow.error.intersection_of_multiple_ways.${featureType}`))();
|
||||
.label(t.html(`operations.follow.error.intersection_of_multiple_ways.${featureType}`))();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ export function behaviorDrawWay(context, wayID, mode, startGraph) {
|
||||
context.ui().flash
|
||||
.duration(4000)
|
||||
.iconName('#iD-icon-no')
|
||||
.label(t(`operations.follow.error.intersection_of_different_ways.${featureType}`))();
|
||||
.label(t.html(`operations.follow.error.intersection_of_different_ways.${featureType}`))();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -501,7 +501,7 @@ export function behaviorDrawWay(context, wayID, mode, startGraph) {
|
||||
context.ui().flash
|
||||
.duration(4000)
|
||||
.iconName('#iD-icon-no')
|
||||
.label(t('operations.follow.error.unknown'))();
|
||||
.label(t.html('operations.follow.error.unknown'))();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { escape } from 'lodash-es';
|
||||
|
||||
import { fileFetcher } from './file_fetcher';
|
||||
import { utilDetect } from '../util/detect';
|
||||
import { utilStringQs } from '../util';
|
||||
@@ -347,14 +349,42 @@ export function coreLocalizer() {
|
||||
};
|
||||
|
||||
// Returns the localized text wrapped in an HTML element encoding the locale info
|
||||
/**
|
||||
* @deprecated This method is considered deprecated. Instead, use the direct DOM manipulating
|
||||
* method `t.append`.
|
||||
*/
|
||||
localizer.t.html = function(stringId, replacements, locale) {
|
||||
const info = localizer.tInfo(stringId, replacements, locale);
|
||||
// text may be empty or undefined if `replacements.default` is
|
||||
return info.text ? localizer.htmlForLocalizedText(info.text, info.locale) : '';
|
||||
// replacement string might be html unsafe, so we need to escape it except if it is explicitly marked as html code
|
||||
replacements = Object.assign({}, replacements);
|
||||
for (var k in replacements) {
|
||||
if (typeof replacements[k] === 'string') {
|
||||
replacements[k] = escape(replacements[k]);
|
||||
}
|
||||
if (typeof replacements[k] === 'object' && typeof replacements[k].html === 'string') {
|
||||
replacements[k] = replacements[k].html;
|
||||
}
|
||||
}
|
||||
|
||||
const info = localizer.tInfo(stringId, replacements, locale);
|
||||
// text may be empty or undefined if `replacements.default` is
|
||||
if (info.text) {
|
||||
return `<span class="localized-text" lang="${info.locale || 'und'}">${info.text}</span>`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
localizer.htmlForLocalizedText = function(text, localeCode) {
|
||||
return `<span class="localized-text" lang="${localeCode || 'unknown'}">${text}</span>`;
|
||||
// Adds localized text wrapped as an HTML span element with locale info to the DOM
|
||||
localizer.t.append = function(stringId, replacements, locale) {
|
||||
return function(selection) {
|
||||
const info = localizer.tInfo(stringId, replacements, locale);
|
||||
return selection.append('span')
|
||||
.attr('class', 'localized-text')
|
||||
.attr('lang', info.locale || 'und')
|
||||
.text((replacements && replacements.prefix || '')
|
||||
+ info.text
|
||||
+ (replacements &&replacements.suffix || ''));
|
||||
};
|
||||
};
|
||||
|
||||
localizer.languageName = (code, options) => {
|
||||
|
||||
@@ -12,6 +12,8 @@ _storage = _storage || (() => {
|
||||
};
|
||||
})();
|
||||
|
||||
const _listeners = {};
|
||||
|
||||
//
|
||||
// corePreferences is an interface for persisting basic key-value strings
|
||||
// within and between iD sessions on the same site.
|
||||
@@ -22,11 +24,13 @@ _storage = _storage || (() => {
|
||||
* @returns {boolean} true if the action succeeded
|
||||
*/
|
||||
function corePreferences(k, v) {
|
||||
|
||||
try {
|
||||
if (arguments.length === 1) return _storage.getItem(k);
|
||||
if (v === undefined) return _storage.getItem(k);
|
||||
else if (v === null) _storage.removeItem(k);
|
||||
else _storage.setItem(k, v);
|
||||
if (_listeners[k]) {
|
||||
_listeners[k].forEach(handler => handler(v));
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
/* eslint-disable no-console */
|
||||
@@ -36,7 +40,12 @@ function corePreferences(k, v) {
|
||||
/* eslint-enable no-console */
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// adds an event listener which is triggered whenever
|
||||
corePreferences.onChange = function(k, handler) {
|
||||
_listeners[k] = _listeners[k] || [];
|
||||
_listeners[k].push(handler);
|
||||
};
|
||||
|
||||
export { corePreferences as prefs };
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import { escape } from 'lodash-es';
|
||||
|
||||
import { fileFetcher } from './file_fetcher';
|
||||
import { actionDiscardTags } from '../actions/discard_tags';
|
||||
@@ -218,7 +219,7 @@ export function coreUploader(context) {
|
||||
};
|
||||
}
|
||||
function formatUser(d) {
|
||||
return '<a href="' + osm.userURL(d) + '" target="_blank">' + d + '</a>';
|
||||
return '<a href="' + osm.userURL(d) + '" target="_blank">' + escape(d) + '</a>';
|
||||
}
|
||||
function entityName(entity) {
|
||||
return utilDisplayName(entity) || (utilDisplayType(entity.id) + ' ' + entity.id);
|
||||
|
||||
@@ -239,7 +239,7 @@ export function modeDragNode(context) {
|
||||
context.ui().flash
|
||||
.duration(4000)
|
||||
.iconName('#iD-icon-no')
|
||||
.label(t('operations.connect.' + isInvalid,
|
||||
.label(t.html('operations.connect.' + isInvalid,
|
||||
{ relation: presetManager.item('type/restriction').name() }
|
||||
))();
|
||||
}
|
||||
@@ -248,7 +248,7 @@ export function modeDragNode(context) {
|
||||
context.ui().flash
|
||||
.duration(3000)
|
||||
.iconName('#iD-icon-no')
|
||||
.label(t('self_intersection.error.' + errorID))();
|
||||
.label(t.html('self_intersection.error.' + errorID))();
|
||||
} else {
|
||||
if (nope) { // about to un-nope, remove hint
|
||||
context.ui().flash
|
||||
|
||||
@@ -12,7 +12,7 @@ export function modeDrawArea(context, wayID, startGraph, button) {
|
||||
.on('rejectedSelfIntersection.modeDrawArea', function() {
|
||||
context.ui().flash
|
||||
.iconName('#iD-icon-no')
|
||||
.label(t('self_intersection.error.areas'))();
|
||||
.label(t.html('self_intersection.error.areas'))();
|
||||
});
|
||||
|
||||
mode.wayID = wayID;
|
||||
|
||||
@@ -12,7 +12,7 @@ export function modeDrawLine(context, wayID, startGraph, button, affix, continui
|
||||
.on('rejectedSelfIntersection.modeDrawLine', function() {
|
||||
context.ui().flash
|
||||
.iconName('#iD-icon-no')
|
||||
.label(t('self_intersection.error.lines'))();
|
||||
.label(t.html('self_intersection.error.lines'))();
|
||||
});
|
||||
|
||||
mode.wayID = wayID;
|
||||
|
||||
@@ -400,7 +400,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
.duration(4000)
|
||||
.iconName('#iD-icon-no')
|
||||
.iconClass('operation disabled')
|
||||
.label(t('operations.scale.' + disabled + '.' + multi))();
|
||||
.label(t.html('operations.scale.' + disabled + '.' + multi))();
|
||||
} else {
|
||||
const pivot = context.projection(extent.center());
|
||||
const annotation = t('operations.scale.annotation.' + (isUp ? 'up' : 'down') + '.feature', { n: selectedIDs.length });
|
||||
|
||||
@@ -78,6 +78,15 @@ export function operationSplit(context, selectedIDs) {
|
||||
};
|
||||
|
||||
|
||||
operation.icon = function() {
|
||||
if (_waysAmount === 'multiple') {
|
||||
return '#iD-operation-split-multiple';
|
||||
} else {
|
||||
return '#iD-operation-split';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
operation.id = 'split';
|
||||
operation.keys = [t('operations.split.key')];
|
||||
operation.title = t('operations.split.title');
|
||||
|
||||
@@ -36,7 +36,11 @@ osmEntity.id.fromOSM = function(type, id) {
|
||||
|
||||
|
||||
osmEntity.id.toOSM = function(id) {
|
||||
return id.slice(1);
|
||||
var match = id.match(/^[cnwr](-?\d+)$/);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
|
||||
@@ -129,7 +133,8 @@ osmEntity.prototype = {
|
||||
|
||||
|
||||
isNew: function() {
|
||||
return this.osmId() < 0;
|
||||
var osmId = osmEntity.id.toOSM(this.id);
|
||||
return osmId.length === 0 || osmId[0] === '-';
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { geoArea as d3_geoArea, geoMercatorRaw as d3_geoMercatorRaw } from 'd3-geo';
|
||||
import { json as d3_json } from 'd3-fetch';
|
||||
import { escape } from 'lodash';
|
||||
|
||||
import { t, localizer } from '../core/localizer';
|
||||
import { geoExtent, geoSphericalDistance } from '../geo';
|
||||
@@ -68,19 +69,19 @@ export function rendererBackgroundSource(data) {
|
||||
|
||||
source.name = function() {
|
||||
var id_safe = source.id.replace(/\./g, '<TX_DOT>');
|
||||
return t('imagery.' + id_safe + '.name', { default: _name });
|
||||
return t('imagery.' + id_safe + '.name', { default: escape(_name) });
|
||||
};
|
||||
|
||||
|
||||
source.label = function() {
|
||||
var id_safe = source.id.replace(/\./g, '<TX_DOT>');
|
||||
return t.html('imagery.' + id_safe + '.name', { default: _name });
|
||||
return t.html('imagery.' + id_safe + '.name', { default: escape(_name) });
|
||||
};
|
||||
|
||||
|
||||
source.description = function() {
|
||||
var id_safe = source.id.replace(/\./g, '<TX_DOT>');
|
||||
return t.html('imagery.' + id_safe + '.description', { default: _description });
|
||||
return t.html('imagery.' + id_safe + '.description', { default: escape(_description) });
|
||||
};
|
||||
|
||||
|
||||
@@ -442,42 +443,22 @@ rendererBackgroundSource.Esri = function(data) {
|
||||
|
||||
|
||||
esri.getMetadata = function(center, tileCoord, callback) {
|
||||
if (esri.id !== 'EsriWorldImagery') {
|
||||
// rest endpoint is not available for ESRI's "clarity" imagery
|
||||
return callback(null, {});
|
||||
}
|
||||
var tileID = tileCoord.slice(0, 3).join('/');
|
||||
var zoom = Math.min(tileCoord[2], esri.zoomExtent[1]);
|
||||
var centerPoint = center[0] + ',' + center[1]; // long, lat (as it should be)
|
||||
var unknown = t('info_panels.background.unknown');
|
||||
var metadataLayer;
|
||||
var vintage = {};
|
||||
var metadata = {};
|
||||
|
||||
if (inflight[tileID]) return;
|
||||
|
||||
switch (true) {
|
||||
case (zoom >= 20 && esri.id === 'EsriWorldImageryClarity'):
|
||||
metadataLayer = 4;
|
||||
break;
|
||||
case zoom >= 19:
|
||||
metadataLayer = 3;
|
||||
break;
|
||||
case zoom >= 17:
|
||||
metadataLayer = 2;
|
||||
break;
|
||||
case zoom >= 13:
|
||||
metadataLayer = 0;
|
||||
break;
|
||||
default:
|
||||
metadataLayer = 99;
|
||||
}
|
||||
|
||||
var url;
|
||||
// build up query using the layer appropriate to the current zoom
|
||||
if (esri.id === 'EsriWorldImagery') {
|
||||
url = 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/';
|
||||
} else if (esri.id === 'EsriWorldImageryClarity') {
|
||||
url = 'https://serviceslab.arcgisonline.com/arcgis/rest/services/Clarity_World_Imagery/MapServer/';
|
||||
}
|
||||
|
||||
url += metadataLayer + '/query?returnGeometry=false&geometry=' + centerPoint + '&inSR=4326&geometryType=esriGeometryPoint&outFields=*&f=json';
|
||||
var url = 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/4/query';
|
||||
url += '?returnGeometry=false&geometry=' + centerPoint + '&inSR=4326&geometryType=esriGeometryPoint&outFields=*&f=json';
|
||||
|
||||
if (!cache[tileID]) {
|
||||
cache[tileID] = {};
|
||||
@@ -486,67 +467,52 @@ rendererBackgroundSource.Esri = function(data) {
|
||||
return callback(null, cache[tileID].metadata);
|
||||
}
|
||||
|
||||
// accurate metadata is only available >= 13
|
||||
if (metadataLayer === 99) {
|
||||
vintage = {
|
||||
start: null,
|
||||
end: null,
|
||||
range: null
|
||||
};
|
||||
metadata = {
|
||||
vintage: null,
|
||||
source: unknown,
|
||||
description: unknown,
|
||||
resolution: unknown,
|
||||
accuracy: unknown
|
||||
};
|
||||
inflight[tileID] = true;
|
||||
d3_json(url)
|
||||
.then(function(result) {
|
||||
delete inflight[tileID];
|
||||
|
||||
callback(null, metadata);
|
||||
result = result.features.map(f => f.attributes)
|
||||
.filter(a => a.MinMapLevel <= zoom && a.MaxMapLevel >= zoom)[0];
|
||||
|
||||
} else {
|
||||
inflight[tileID] = true;
|
||||
d3_json(url)
|
||||
.then(function(result) {
|
||||
delete inflight[tileID];
|
||||
if (!result) {
|
||||
throw new Error('Unknown Error');
|
||||
} else if (result.features && result.features.length < 1) {
|
||||
throw new Error('No Results');
|
||||
} else if (result.error && result.error.message) {
|
||||
throw new Error(result.error.message);
|
||||
}
|
||||
if (!result) {
|
||||
throw new Error('Unknown Error');
|
||||
} else if (result.features && result.features.length < 1) {
|
||||
throw new Error('No Results');
|
||||
} else if (result.error && result.error.message) {
|
||||
throw new Error(result.error.message);
|
||||
}
|
||||
|
||||
// pass through the discrete capture date from metadata
|
||||
var captureDate = localeDateString(result.features[0].attributes.SRC_DATE2);
|
||||
vintage = {
|
||||
start: captureDate,
|
||||
end: captureDate,
|
||||
range: captureDate
|
||||
};
|
||||
metadata = {
|
||||
vintage: vintage,
|
||||
source: clean(result.features[0].attributes.NICE_NAME),
|
||||
description: clean(result.features[0].attributes.NICE_DESC),
|
||||
resolution: clean(+parseFloat(result.features[0].attributes.SRC_RES).toFixed(4)),
|
||||
accuracy: clean(+parseFloat(result.features[0].attributes.SRC_ACC).toFixed(4))
|
||||
};
|
||||
// pass through the discrete capture date from metadata
|
||||
var captureDate = localeDateString(result.SRC_DATE2);
|
||||
vintage = {
|
||||
start: captureDate,
|
||||
end: captureDate,
|
||||
range: captureDate
|
||||
};
|
||||
metadata = {
|
||||
vintage: vintage,
|
||||
source: clean(result.NICE_NAME),
|
||||
description: clean(result.NICE_DESC),
|
||||
resolution: clean(+parseFloat(result.SRC_RES).toFixed(4)),
|
||||
accuracy: clean(+parseFloat(result.SRC_ACC).toFixed(4))
|
||||
};
|
||||
|
||||
// append units - meters
|
||||
if (isFinite(metadata.resolution)) {
|
||||
metadata.resolution += ' m';
|
||||
}
|
||||
if (isFinite(metadata.accuracy)) {
|
||||
metadata.accuracy += ' m';
|
||||
}
|
||||
// append units - meters
|
||||
if (isFinite(metadata.resolution)) {
|
||||
metadata.resolution += ' m';
|
||||
}
|
||||
if (isFinite(metadata.accuracy)) {
|
||||
metadata.accuracy += ' m';
|
||||
}
|
||||
|
||||
cache[tileID].metadata = metadata;
|
||||
if (callback) callback(null, metadata);
|
||||
})
|
||||
.catch(function(err) {
|
||||
delete inflight[tileID];
|
||||
if (callback) callback(err.message);
|
||||
});
|
||||
}
|
||||
cache[tileID].metadata = metadata;
|
||||
if (callback) callback(null, metadata);
|
||||
})
|
||||
.catch(function(err) {
|
||||
delete inflight[tileID];
|
||||
if (callback) callback(err.message);
|
||||
});
|
||||
|
||||
|
||||
function clean(val) {
|
||||
|
||||
@@ -239,7 +239,7 @@ export function rendererTileLayer(context) {
|
||||
|
||||
debug
|
||||
.selectAll('.tile-label-debug-coord')
|
||||
.html(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; });
|
||||
.text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; });
|
||||
|
||||
debug
|
||||
.selectAll('.tile-label-debug-vintage')
|
||||
@@ -247,9 +247,11 @@ export function rendererTileLayer(context) {
|
||||
var span = d3_select(this);
|
||||
var center = context.projection.invert(tileCenter(d));
|
||||
_source.getMetadata(center, d, function(err, result) {
|
||||
span.html((result && result.vintage && result.vintage.range) ||
|
||||
t('info_panels.background.vintage') + ': ' + t('info_panels.background.unknown')
|
||||
);
|
||||
if (result && result.vintage && result.vintage.range) {
|
||||
span.text(result.vintage.range);
|
||||
} else {
|
||||
span.html(t.html('info_panels.background.vintage') + ': ' + t.html('info_panels.background.unknown'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -276,22 +276,22 @@ export default {
|
||||
controlsEnter
|
||||
.append('button')
|
||||
.on('click.back', step(-1))
|
||||
.html('◄');
|
||||
.text('◄');
|
||||
|
||||
controlsEnter
|
||||
.append('button')
|
||||
.on('click.rotate-ccw', rotate(-90))
|
||||
.html('⤿');
|
||||
.text('⤿');
|
||||
|
||||
controlsEnter
|
||||
.append('button')
|
||||
.on('click.rotate-cw', rotate(90))
|
||||
.html('⤾');
|
||||
.text('⤾');
|
||||
|
||||
controlsEnter
|
||||
.append('button')
|
||||
.on('click.forward', step(1))
|
||||
.html('►');
|
||||
.text('►');
|
||||
|
||||
wrapEnter
|
||||
.append('div')
|
||||
@@ -428,7 +428,7 @@ export default {
|
||||
|
||||
var wrap = context.container().select('.photoviewer .kartaview-wrapper');
|
||||
var imageWrap = wrap.selectAll('.kartaview-image-wrap');
|
||||
var attribution = wrap.selectAll('.photo-attribution').html('');
|
||||
var attribution = wrap.selectAll('.photo-attribution').text('');
|
||||
|
||||
wrap
|
||||
.transition()
|
||||
@@ -455,22 +455,22 @@ export default {
|
||||
.attr('class', 'captured_by')
|
||||
.attr('target', '_blank')
|
||||
.attr('href', 'https://kartaview.org/user/' + encodeURIComponent(d.captured_by))
|
||||
.html('@' + d.captured_by);
|
||||
.text('@' + d.captured_by);
|
||||
|
||||
attribution
|
||||
.append('span')
|
||||
.html('|');
|
||||
.text('|');
|
||||
}
|
||||
|
||||
if (d.captured_at) {
|
||||
attribution
|
||||
.append('span')
|
||||
.attr('class', 'captured_at')
|
||||
.html(localeDateString(d.captured_at));
|
||||
.text(localeDateString(d.captured_at));
|
||||
|
||||
attribution
|
||||
.append('span')
|
||||
.html('|');
|
||||
.text('|');
|
||||
}
|
||||
|
||||
attribution
|
||||
@@ -478,7 +478,7 @@ export default {
|
||||
.attr('class', 'image-link')
|
||||
.attr('target', '_blank')
|
||||
.attr('href', 'https://kartaview.org/details/' + d.sequence_id + '/' + d.sequence_index)
|
||||
.html('kartaview.org');
|
||||
.text('kartaview.org');
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
+23
-12
@@ -458,10 +458,13 @@ function _upgradeTags(tags, loc) {
|
||||
return changed ? { newTags: newTags, matched: null } : null;
|
||||
}
|
||||
|
||||
// Order the [key,value,name] tuples - test primary before alternate
|
||||
// Order the [key,value,name] tuples - test primary names before alternate names
|
||||
const tuples = gatherTuples(tryKVs, tryNames);
|
||||
let foundPrimary = false;
|
||||
let bestItem;
|
||||
|
||||
for (let i = 0; i < tuples.length; i++) {
|
||||
// Test [key,value,name] tuples against the NSI matcher until we get a primary match or exhaust all options.
|
||||
for (let i = 0; (i < tuples.length && !foundPrimary); i++) {
|
||||
const tuple = tuples[i];
|
||||
const hits = _nsi.matcher.match(tuple.k, tuple.v, tuple.n, loc); // Attempt to match an item in NSI
|
||||
|
||||
@@ -470,14 +473,15 @@ function _upgradeTags(tags, loc) {
|
||||
|
||||
// A match may contain multiple results, the first one is likely the best one for this location
|
||||
// e.g. `['pfk-a54c14', 'kfc-1ff19c', 'kfc-658eea']`
|
||||
let itemID, item;
|
||||
for (let j = 0; j < hits.length; j++) {
|
||||
const hit = hits[j];
|
||||
itemID = hit.itemID;
|
||||
const isPrimary = (hits[j].match === 'primary');
|
||||
const itemID = hit.itemID;
|
||||
if (_nsi.dissolved[itemID]) continue; // Don't upgrade to a dissolved item
|
||||
|
||||
item = _nsi.ids.get(itemID);
|
||||
const item = _nsi.ids.get(itemID);
|
||||
if (!item) continue;
|
||||
|
||||
const mainTag = item.mainTag; // e.g. `brand:wikidata`
|
||||
const itemQID = item.tags[mainTag]; // e.g. `brand:wikidata` qid
|
||||
const notQID = newTags[`not:${mainTag}`]; // e.g. `not:brand:wikidata` qid
|
||||
@@ -486,18 +490,25 @@ function _upgradeTags(tags, loc) {
|
||||
(!itemQID || itemQID === notQID) || // No `*:wikidata` or matched a `not:*:wikidata`
|
||||
(newTags.office && !item.tags.office) // feature may be a corporate office for a brand? - #6416
|
||||
) {
|
||||
item = null;
|
||||
continue; // continue looking
|
||||
} else {
|
||||
break; // use `item`
|
||||
}
|
||||
|
||||
// If we get here, the hit is good..
|
||||
if (!bestItem || isPrimary) {
|
||||
bestItem = item;
|
||||
if (isPrimary) {
|
||||
foundPrimary = true;
|
||||
}
|
||||
break; // can ignore the rest of the hits from this match
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Can't use any of these hits, try next tuple..
|
||||
if (!item) continue;
|
||||
|
||||
// At this point we have matched a canonical item and can suggest tag upgrades..
|
||||
item = JSON.parse(JSON.stringify(item)); // deep copy
|
||||
// At this point we have matched a canonical item and can suggest tag upgrades..
|
||||
if (bestItem) {
|
||||
const itemID = bestItem.id;
|
||||
const item = JSON.parse(JSON.stringify(bestItem)); // deep copy
|
||||
const tkv = item.tkv;
|
||||
const parts = tkv.split('/', 3); // tkv = "tree/key/value"
|
||||
const k = parts[1];
|
||||
|
||||
@@ -589,7 +589,7 @@ export default {
|
||||
|
||||
|
||||
userURL: function(username) {
|
||||
return urlroot + '/user/' + username;
|
||||
return urlroot + '/user/' + encodeURIComponent(username);
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -544,12 +544,12 @@ export default {
|
||||
controlsEnter
|
||||
.append('button')
|
||||
.on('click.back', step(-1))
|
||||
.html('◄');
|
||||
.text('◄');
|
||||
|
||||
controlsEnter
|
||||
.append('button')
|
||||
.on('click.forward', step(1))
|
||||
.html('►');
|
||||
.text('►');
|
||||
|
||||
|
||||
// create working canvas for stitching together images
|
||||
@@ -794,7 +794,7 @@ export default {
|
||||
|
||||
label
|
||||
.append('span')
|
||||
.html(t.html('streetside.hires'));
|
||||
.call(t.append('streetside.hires'));
|
||||
|
||||
|
||||
let captureInfo = line1
|
||||
@@ -810,18 +810,18 @@ export default {
|
||||
.attr('class', 'captured_by')
|
||||
.attr('target', '_blank')
|
||||
.attr('href', 'https://www.microsoft.com/en-us/maps/streetside')
|
||||
.html('©' + yyyy + ' Microsoft');
|
||||
.text('©' + yyyy + ' Microsoft');
|
||||
|
||||
captureInfo
|
||||
.append('span')
|
||||
.html('|');
|
||||
.text('|');
|
||||
}
|
||||
|
||||
if (d.captured_at) {
|
||||
captureInfo
|
||||
.append('span')
|
||||
.attr('class', 'captured_at')
|
||||
.html(localeTimestamp(d.captured_at));
|
||||
.text(localeTimestamp(d.captured_at));
|
||||
}
|
||||
|
||||
// Add image links
|
||||
@@ -835,7 +835,7 @@ export default {
|
||||
.attr('target', '_blank')
|
||||
.attr('href', 'https://www.bing.com/maps?cp=' + d.loc[1] + '~' + d.loc[0] +
|
||||
'&lvl=17&dir=' + d.ca + '&style=x&v=2&sV=1')
|
||||
.html(t.html('streetside.view_on_bing'));
|
||||
.call(t.append('streetside.view_on_bing'));
|
||||
|
||||
line2
|
||||
.append('a')
|
||||
@@ -843,7 +843,7 @@ export default {
|
||||
.attr('target', '_blank')
|
||||
.attr('href', 'https://www.bing.com/maps/privacyreport/streetsideprivacyreport?bubbleid=' +
|
||||
encodeURIComponent(d.key) + '&focus=photo&lat=' + d.loc[1] + '&lng=' + d.loc[0] + '&z=17')
|
||||
.html(t.html('streetside.report'));
|
||||
.call(t.append('streetside.report'));
|
||||
|
||||
|
||||
let bubbleIdQuadKey = d.key.toString(4);
|
||||
|
||||
@@ -315,6 +315,21 @@ export function svgData(projection, context, dispatch) {
|
||||
}
|
||||
|
||||
|
||||
function stringifyGeojsonProperties(feature) {
|
||||
const properties = feature.properties;
|
||||
for (const key in properties) {
|
||||
const property = properties[key];
|
||||
if (typeof property === 'number' || typeof property === 'boolean' || Array.isArray(property)) {
|
||||
properties[key] = property.toString();
|
||||
} else if (property === null) {
|
||||
properties[key] = 'null';
|
||||
} else if (typeof property === 'object') {
|
||||
properties[key] = JSON.stringify(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drawData.setFile = function(extension, data) {
|
||||
_template = null;
|
||||
_fileList = null;
|
||||
@@ -332,6 +347,11 @@ export function svgData(projection, context, dispatch) {
|
||||
case '.geojson':
|
||||
case '.json':
|
||||
gj = JSON.parse(data);
|
||||
if (gj.type === 'FeatureCollection') {
|
||||
gj.features.forEach(stringifyGeojsonProperties);
|
||||
} else if (gj.type === 'Feature') {
|
||||
stringifyGeojsonProperties(gj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ export function uiAccount(context) {
|
||||
logoutLink.append('a')
|
||||
.attr('class', 'logout')
|
||||
.attr('href', '#')
|
||||
.html(t.html('logout'))
|
||||
.call(t.append('logout'))
|
||||
.on('click.logout', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
osm.logout();
|
||||
|
||||
@@ -56,7 +56,7 @@ export function uiAttribution(context) {
|
||||
attribution
|
||||
.append('span')
|
||||
.attr('class', 'attribution-text')
|
||||
.html(terms_text);
|
||||
.text(terms_text);
|
||||
})
|
||||
.merge(attributions);
|
||||
|
||||
@@ -76,7 +76,7 @@ export function uiAttribution(context) {
|
||||
.merge(copyright);
|
||||
|
||||
copyright
|
||||
.html(String);
|
||||
.text(String);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ export function uiChangesetEditor(context) {
|
||||
.call(svgIcon('#iD-icon-alert', 'inline'))
|
||||
.attr('href', t('commit.google_warning_link'))
|
||||
.append('span')
|
||||
.html(t.html('commit.google_warning'));
|
||||
.call(t.append('commit.google_warning'));
|
||||
|
||||
commentEnter
|
||||
.transition()
|
||||
|
||||
@@ -221,7 +221,7 @@ export function uiCommit(context) {
|
||||
headerTitle
|
||||
.append('div')
|
||||
.append('h2')
|
||||
.html(t.html('commit.title'));
|
||||
.call(t.append('commit.title'));
|
||||
|
||||
headerTitle
|
||||
.append('button')
|
||||
@@ -280,7 +280,7 @@ export function uiCommit(context) {
|
||||
prose = prose.enter()
|
||||
.append('p')
|
||||
.attr('class', 'commit-info')
|
||||
.html(t.html('commit.upload_explanation'))
|
||||
.call(t.append('commit.upload_explanation'))
|
||||
.merge(prose);
|
||||
|
||||
// always check if this has changed, but only update prose.html()
|
||||
@@ -303,12 +303,12 @@ export function uiCommit(context) {
|
||||
userLink
|
||||
.append('a')
|
||||
.attr('class', 'user-info')
|
||||
.html(user.display_name)
|
||||
.text(user.display_name)
|
||||
.attr('href', osm.userURL(user.display_name))
|
||||
.attr('target', '_blank');
|
||||
|
||||
prose
|
||||
.html(t.html('commit.upload_explanation_with_user', { user: userLink.html() }));
|
||||
.html(t.html('commit.upload_explanation_with_user', { user: { html: userLink.html() } }));
|
||||
});
|
||||
|
||||
|
||||
@@ -339,7 +339,7 @@ export function uiCommit(context) {
|
||||
|
||||
labelEnter
|
||||
.append('span')
|
||||
.html(t.html('commit.request_review'));
|
||||
.call(t.append('commit.request_review'));
|
||||
|
||||
// Update
|
||||
requestReview = requestReview
|
||||
@@ -364,7 +364,7 @@ export function uiCommit(context) {
|
||||
.attr('class', 'secondary-action button cancel-button')
|
||||
.append('span')
|
||||
.attr('class', 'label')
|
||||
.html(t.html('commit.cancel'));
|
||||
.call(t.append('commit.cancel'));
|
||||
|
||||
var uploadButton = buttonEnter
|
||||
.append('button')
|
||||
@@ -372,7 +372,7 @@ export function uiCommit(context) {
|
||||
|
||||
uploadButton.append('span')
|
||||
.attr('class', 'label')
|
||||
.html(t.html('commit.save'));
|
||||
.call(t.append('commit.save'));
|
||||
|
||||
var uploadBlockerTooltipText = getUploadBlockerMessage();
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export function uiConfirm(selection) {
|
||||
.on('click.confirm', function() {
|
||||
modalSelection.remove();
|
||||
})
|
||||
.html(t.html('confirm.okay'))
|
||||
.call(t.append('confirm.okay'))
|
||||
.node()
|
||||
.focus();
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ export function uiConflicts(context) {
|
||||
|
||||
headerEnter
|
||||
.append('h2')
|
||||
.html(t.html('save.conflict.header'));
|
||||
.call(t.append('save.conflict.header'));
|
||||
|
||||
var bodyEnter = selection.selectAll('.body')
|
||||
.data([0])
|
||||
@@ -77,7 +77,7 @@ export function uiConflicts(context) {
|
||||
var conflictsHelpEnter = bodyEnter
|
||||
.append('div')
|
||||
.attr('class', 'conflicts-help')
|
||||
.html(t.html('save.conflict.help'));
|
||||
.call(t.append('save.conflict.help'));
|
||||
|
||||
|
||||
// Download changes link
|
||||
@@ -110,7 +110,7 @@ export function uiConflicts(context) {
|
||||
linkEnter
|
||||
.call(svgIcon('#iD-icon-load', 'inline'))
|
||||
.append('span')
|
||||
.html(t.html('save.conflict.download_changes'));
|
||||
.call(t.append('save.conflict.download_changes'));
|
||||
|
||||
|
||||
bodyEnter
|
||||
@@ -123,7 +123,7 @@ export function uiConflicts(context) {
|
||||
.attr('class', 'conflicts-done')
|
||||
.attr('opacity', 0)
|
||||
.style('display', 'none')
|
||||
.html(t.html('save.conflict.done'));
|
||||
.call(t.append('save.conflict.done'));
|
||||
|
||||
var buttonsEnter = bodyEnter
|
||||
.append('div')
|
||||
@@ -133,13 +133,13 @@ export function uiConflicts(context) {
|
||||
.append('button')
|
||||
.attr('disabled', _conflictList.length > 1)
|
||||
.attr('class', 'action conflicts-button col6')
|
||||
.html(t.html('save.title'))
|
||||
.call(t.append('save.title'))
|
||||
.on('click.try_again', tryAgain);
|
||||
|
||||
buttonsEnter
|
||||
.append('button')
|
||||
.attr('class', 'secondary-action conflicts-button col6')
|
||||
.html(t.html('confirm.cancel'))
|
||||
.call(t.append('confirm.cancel'))
|
||||
.on('click.cancel', cancel);
|
||||
}
|
||||
|
||||
@@ -177,13 +177,13 @@ export function uiConflicts(context) {
|
||||
conflictEnter
|
||||
.append('h4')
|
||||
.attr('class', 'conflict-count')
|
||||
.html(t.html('save.conflict.count', { num: index + 1, total: _conflictList.length }));
|
||||
.call(t.append('save.conflict.count', { num: index + 1, total: _conflictList.length }));
|
||||
|
||||
conflictEnter
|
||||
.append('a')
|
||||
.attr('class', 'conflict-description')
|
||||
.attr('href', '#')
|
||||
.html(function(d) { return d.name; })
|
||||
.text(function(d) { return d.name; })
|
||||
.on('click', function(d3_event, d) {
|
||||
d3_event.preventDefault();
|
||||
zoomToEntity(d.id);
|
||||
@@ -265,7 +265,7 @@ export function uiConflicts(context) {
|
||||
|
||||
labelEnter
|
||||
.append('span')
|
||||
.html(function(d) { return d.text; });
|
||||
.text(function(d) { return d.text; });
|
||||
|
||||
// update
|
||||
choicesEnter
|
||||
|
||||
@@ -39,7 +39,7 @@ export function uiContributors(context) {
|
||||
.attr('class', 'user-link')
|
||||
.attr('href', function(d) { return osm.userURL(d); })
|
||||
.attr('target', '_blank')
|
||||
.html(String);
|
||||
.text(String);
|
||||
|
||||
if (u.length > limit) {
|
||||
var count = d3_select(document.createElement('span'));
|
||||
@@ -51,14 +51,14 @@ export function uiContributors(context) {
|
||||
.attr('href', function() {
|
||||
return osm.changesetsURL(context.map().center(), context.map().zoom());
|
||||
})
|
||||
.html(othersNum);
|
||||
.text(othersNum);
|
||||
|
||||
wrap.append('span')
|
||||
.html(t.html('contributors.truncated_list', { n: othersNum, users: userList.html(), count: count.html() }));
|
||||
.html(t.html('contributors.truncated_list', { n: othersNum, users: { html: userList.html() }, count: { html: count.html() } }));
|
||||
|
||||
} else {
|
||||
wrap.append('span')
|
||||
.html(t.html('contributors.list', { users: userList.html() }));
|
||||
.html(t.html('contributors.list', { users: { html: userList.html() } }));
|
||||
}
|
||||
|
||||
if (!u.length) {
|
||||
|
||||
@@ -34,7 +34,7 @@ export function uiDataEditor(context) {
|
||||
|
||||
headerEnter
|
||||
.append('h2')
|
||||
.html(t.html('map_data.title'));
|
||||
.call(t.append('map_data.title'));
|
||||
|
||||
|
||||
var body = selection.selectAll('.body')
|
||||
|
||||
@@ -32,7 +32,7 @@ export function uiDataHeader() {
|
||||
headerEnter
|
||||
.append('div')
|
||||
.attr('class', 'data-header-label')
|
||||
.html(t.html('map_data.layers.custom.title'));
|
||||
.call(t.append('map_data.layers.custom.title'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ export function uiEditMenu(context) {
|
||||
.call(tooltip)
|
||||
.append('div')
|
||||
.attr('class', 'icon-wrap')
|
||||
.call(svgIcon('#iD-operation-' + d.id, 'operation'));
|
||||
.call(svgIcon(d.icon && d.icon() || '#iD-operation-' + d.id, 'operation'));
|
||||
});
|
||||
|
||||
if (showLabels) {
|
||||
|
||||
@@ -165,7 +165,10 @@ export function uiEntityEditor(context) {
|
||||
for (var k in changed) {
|
||||
if (!k) continue;
|
||||
var v = changed[k];
|
||||
if (v !== undefined || tags.hasOwnProperty(k)) {
|
||||
if (typeof v === 'object') {
|
||||
// a "key only" tag change
|
||||
tags[k] = tags[v.oldKey];
|
||||
} else if (v !== undefined || tags.hasOwnProperty(k)) {
|
||||
tags[k] = v;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ export function uiFeatureInfo(context) {
|
||||
var hiddenList = features.hidden().map(function(k) {
|
||||
if (stats[k]) {
|
||||
count += stats[k];
|
||||
return t('inspector.title_count', { title: t.html('feature.' + k + '.description'), count: stats[k] });
|
||||
return t.html('inspector.title_count', { title: { html: t.html('feature.' + k + '.description') }, count: stats[k] });
|
||||
}
|
||||
return null;
|
||||
}).filter(Boolean);
|
||||
@@ -26,7 +26,7 @@ export function uiFeatureInfo(context) {
|
||||
selection.append('a')
|
||||
.attr('class', 'chip')
|
||||
.attr('href', '#')
|
||||
.html(t.html('feature_info.hidden_warning', { count: count }))
|
||||
.call(t.append('feature_info.hidden_warning', { count: count }))
|
||||
.call(tooltipBehavior)
|
||||
.on('click', function(d3_event) {
|
||||
tooltipBehavior.hide();
|
||||
|
||||
@@ -34,7 +34,7 @@ export function uiFeatureList(context) {
|
||||
|
||||
header
|
||||
.append('h2')
|
||||
.html(t.html('inspector.feature_list'));
|
||||
.call(t.append('inspector.feature_list'));
|
||||
|
||||
var searchWrap = selection
|
||||
.append('div')
|
||||
@@ -255,7 +255,8 @@ export function uiFeatureList(context) {
|
||||
.attr('class', 'entity-name');
|
||||
|
||||
list.selectAll('.no-results-item .entity-name')
|
||||
.html(t.html('geocoder.no_results_worldwide'));
|
||||
.html('')
|
||||
.call(t.append('geocoder.no_results_worldwide'));
|
||||
|
||||
if (services.geocoder) {
|
||||
list.selectAll('.geocode-item')
|
||||
@@ -268,7 +269,7 @@ export function uiFeatureList(context) {
|
||||
.attr('class', 'label')
|
||||
.append('span')
|
||||
.attr('class', 'entity-name')
|
||||
.html(t.html('geocoder.search'));
|
||||
.call(t.append('geocoder.search'));
|
||||
}
|
||||
|
||||
list.selectAll('.no-results-item')
|
||||
@@ -304,12 +305,12 @@ export function uiFeatureList(context) {
|
||||
label
|
||||
.append('span')
|
||||
.attr('class', 'entity-type')
|
||||
.html(function(d) { return d.type; });
|
||||
.text(function(d) { return d.type; });
|
||||
|
||||
label
|
||||
.append('span')
|
||||
.attr('class', 'entity-name')
|
||||
.html(function(d) { return d.name; });
|
||||
.text(function(d) { return d.name; });
|
||||
|
||||
enter
|
||||
.style('opacity', 0)
|
||||
|
||||
+10
-10
@@ -54,15 +54,15 @@ export function uiFieldHelp(context, fieldName) {
|
||||
var fieldHelpHeadings = {};
|
||||
|
||||
var replacements = {
|
||||
distField: t.html('restriction.controls.distance'),
|
||||
viaField: t.html('restriction.controls.via'),
|
||||
fromShadow: icon('#iD-turn-shadow', 'inline shadow from'),
|
||||
allowShadow: icon('#iD-turn-shadow', 'inline shadow allow'),
|
||||
restrictShadow: icon('#iD-turn-shadow', 'inline shadow restrict'),
|
||||
onlyShadow: icon('#iD-turn-shadow', 'inline shadow only'),
|
||||
allowTurn: icon('#iD-turn-yes', 'inline turn'),
|
||||
restrictTurn: icon('#iD-turn-no', 'inline turn'),
|
||||
onlyTurn: icon('#iD-turn-only', 'inline turn')
|
||||
distField: { html: t.html('restriction.controls.distance') },
|
||||
viaField: { html: t.html('restriction.controls.via') },
|
||||
fromShadow: { html: icon('#iD-turn-shadow', 'inline shadow from') },
|
||||
allowShadow: { html: icon('#iD-turn-shadow', 'inline shadow allow') },
|
||||
restrictShadow: { html: icon('#iD-turn-shadow', 'inline shadow restrict') },
|
||||
onlyShadow: { html: icon('#iD-turn-shadow', 'inline shadow only') },
|
||||
allowTurn: { html: icon('#iD-turn-yes', 'inline turn') },
|
||||
restrictTurn: { html: icon('#iD-turn-no', 'inline turn') },
|
||||
onlyTurn: { html: icon('#iD-turn-only', 'inline turn') }
|
||||
};
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ export function uiFieldHelp(context, fieldName) {
|
||||
titleEnter
|
||||
.append('h2')
|
||||
.attr('class', ((localizer.textDirection() === 'rtl') ? 'fr' : 'fl'))
|
||||
.html(t.html('help.field.' + fieldName + '.title'));
|
||||
.call(t.append('help.field.' + fieldName + '.title'));
|
||||
|
||||
titleEnter
|
||||
.append('button')
|
||||
|
||||
@@ -288,7 +288,7 @@ export function uiFieldAddress(field, context) {
|
||||
})
|
||||
.attr('title', function(subfield) {
|
||||
var val = tags[field.key + ':' + subfield.id];
|
||||
return val && Array.isArray(val) && val.filter(Boolean).join('\n');
|
||||
return (val && Array.isArray(val)) ? val.filter(Boolean).join('\n') : undefined;
|
||||
})
|
||||
.classed('mixed', function(subfield) {
|
||||
return Array.isArray(tags[field.key + ':' + subfield.id]);
|
||||
|
||||
@@ -83,7 +83,8 @@ export function uiFieldCheck(field, context) {
|
||||
var icon = pseudoDirection ? '#iD-icon-forward' : '#iD-icon-backward';
|
||||
|
||||
selection.selectAll('.reverser-span')
|
||||
.html(t.html('inspector.check.reverser'))
|
||||
.html('')
|
||||
.call(t.append('inspector.check.reverser'))
|
||||
.call(svgIcon(icon, 'inline'));
|
||||
|
||||
return selection;
|
||||
|
||||
@@ -527,13 +527,13 @@ export function uiFieldCombo(field, context) {
|
||||
}
|
||||
|
||||
chips.select('span')
|
||||
.html(function(d) { return d.value; });
|
||||
.text(function(d) { return d.value; });
|
||||
|
||||
chips.select('a')
|
||||
.attr('href', '#')
|
||||
.on('click', removeMultikey)
|
||||
.attr('class', 'remove')
|
||||
.html('×');
|
||||
.text('×');
|
||||
|
||||
} else {
|
||||
var isMixed = Array.isArray(tags[field.key]);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import { select as d3_select } from 'd3-selection';
|
||||
import _debounce from 'lodash-es/debounce';
|
||||
import * as countryCoder from '@ideditor/country-coder';
|
||||
|
||||
import { presetManager } from '../../presets';
|
||||
@@ -21,6 +22,7 @@ export function uiFieldText(field, context) {
|
||||
var dispatch = d3_dispatch('change');
|
||||
var input = d3_select(null);
|
||||
var outlinkButton = d3_select(null);
|
||||
var wrap = d3_select(null);
|
||||
var _entityIDs = [];
|
||||
var _tags;
|
||||
var _phoneFormats = {};
|
||||
@@ -62,7 +64,7 @@ export function uiFieldText(field, context) {
|
||||
calcLocked();
|
||||
var isLocked = field.locked();
|
||||
|
||||
var wrap = selection.selectAll('.form-field-input-wrap')
|
||||
wrap = selection.selectAll('.form-field-input-wrap')
|
||||
.data([0]);
|
||||
|
||||
wrap = wrap.enter()
|
||||
@@ -171,9 +173,67 @@ export function uiFieldText(field, context) {
|
||||
if (value) window.open(value, '_blank');
|
||||
})
|
||||
.merge(outlinkButton);
|
||||
} else if (field.key.split(':').includes('colour')) {
|
||||
input.attr('type', 'text');
|
||||
|
||||
updateColourPreview();
|
||||
}
|
||||
}
|
||||
|
||||
function isColourValid(colour) {
|
||||
if (!colour.match(/^(#([0-9a-fA-F]{3}){1,2}|\w+)$/)) {
|
||||
// OSM only supports hex or named colors
|
||||
return false;
|
||||
} else if (!CSS.supports('color', colour) || ['unset', 'inherit', 'initial', 'revert'].includes(colour)) {
|
||||
// see https://stackoverflow.com/a/68217760/1627467
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function updateColourPreview() {
|
||||
wrap.selectAll('.colour-preview')
|
||||
.remove();
|
||||
|
||||
const colour = utilGetSetValue(input);
|
||||
|
||||
if (!isColourValid(colour) && colour !== '') return;
|
||||
|
||||
var colourSelector = wrap.selectAll('.colour-selector')
|
||||
.data([0]);
|
||||
outlinkButton = wrap.selectAll('.colour-preview')
|
||||
.data([colour]);
|
||||
|
||||
colourSelector
|
||||
.enter()
|
||||
.append('input')
|
||||
.attr('type', 'color')
|
||||
.attr('class', 'form-field-button colour-selector')
|
||||
.attr('value', colour)
|
||||
.on('input', _debounce(function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
var colour = this.value;
|
||||
if (!isColourValid(colour)) return;
|
||||
utilGetSetValue(input, this.value);
|
||||
change()();
|
||||
updateColourPreview();
|
||||
}, 100));
|
||||
|
||||
outlinkButton = outlinkButton
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'form-field-button colour-preview')
|
||||
.append('div')
|
||||
.style('background-color', d => d)
|
||||
.attr('class', 'colour-box');
|
||||
if (colour === '') {
|
||||
outlinkButton = outlinkButton
|
||||
.call(svgIcon('#iD-icon-edit'));
|
||||
}
|
||||
outlinkButton
|
||||
.on('click', () => wrap.select('.colour-selector').node().click())
|
||||
.merge(outlinkButton);
|
||||
}
|
||||
|
||||
|
||||
function updatePhonePlaceholder() {
|
||||
if (input.empty() || !Object.keys(_phoneFormats).length) return;
|
||||
@@ -186,11 +246,17 @@ export function uiFieldText(field, context) {
|
||||
|
||||
|
||||
function validIdentifierValueForLink() {
|
||||
const value = utilGetSetValue(input).trim().split(';')[0];
|
||||
const value = utilGetSetValue(input).trim();
|
||||
|
||||
if (field.type === 'url' && value) return value;
|
||||
if (field.type === 'url' && value) {
|
||||
try {
|
||||
return (new URL(value)).href;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (field.type === 'identifier' && field.pattern) {
|
||||
return value && value.match(new RegExp(field.pattern));
|
||||
return value && value.match(new RegExp(field.pattern))[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -251,6 +317,8 @@ export function uiFieldText(field, context) {
|
||||
.attr('placeholder', isMixed ? t('inspector.multiple_values') : (field.placeholder() || t('inspector.unknown')))
|
||||
.classed('mixed', isMixed);
|
||||
|
||||
if (field.key.split(':').includes('colour')) updateColourPreview();
|
||||
|
||||
if (outlinkButton && !outlinkButton.empty()) {
|
||||
var disabled = !validIdentifierValueForLink();
|
||||
outlinkButton.classed('disabled', disabled);
|
||||
|
||||
@@ -77,7 +77,7 @@ export function uiFieldLanes(field, context) {
|
||||
.append('text')
|
||||
.attr('y', 40)
|
||||
.attr('x', 14)
|
||||
.html('▲');
|
||||
.text('▲');
|
||||
|
||||
enter
|
||||
.append('g')
|
||||
@@ -85,7 +85,7 @@ export function uiFieldLanes(field, context) {
|
||||
.append('text')
|
||||
.attr('y', 40)
|
||||
.attr('x', 14)
|
||||
.html('▲▼');
|
||||
.text('▲▼');
|
||||
|
||||
enter
|
||||
.append('g')
|
||||
@@ -93,7 +93,7 @@ export function uiFieldLanes(field, context) {
|
||||
.append('text')
|
||||
.attr('y', 40)
|
||||
.attr('x', 14)
|
||||
.html('▼');
|
||||
.text('▼');
|
||||
|
||||
|
||||
lane = lane
|
||||
|
||||
@@ -374,7 +374,7 @@ export function uiFieldLocalized(field, context) {
|
||||
text
|
||||
.append('span')
|
||||
.attr('class', 'label-textvalue')
|
||||
.html(t.html('translate.localized_translation_label'));
|
||||
.call(t.append('translate.localized_translation_label'));
|
||||
|
||||
text
|
||||
.append('span')
|
||||
|
||||
@@ -129,7 +129,7 @@ export function uiFieldRadio(field, context) {
|
||||
.append('span')
|
||||
.attr('class', 'label structure-label-type')
|
||||
.attr('for', 'preset-input-' + selected)
|
||||
.html(t.html('inspector.radio.structure.type'));
|
||||
.call(t.append('inspector.radio.structure.type'));
|
||||
|
||||
typeEnter
|
||||
.append('div')
|
||||
@@ -174,7 +174,7 @@ export function uiFieldRadio(field, context) {
|
||||
.append('span')
|
||||
.attr('class', 'label structure-label-layer')
|
||||
.attr('for', 'preset-input-layer')
|
||||
.html(t.html('inspector.radio.structure.layer'));
|
||||
.call(t.append('inspector.radio.structure.layer'));
|
||||
|
||||
layerEnter
|
||||
.append('div')
|
||||
@@ -302,9 +302,9 @@ export function uiFieldRadio(field, context) {
|
||||
var selection = radios.filter(function() { return this.checked; });
|
||||
|
||||
if (selection.empty()) {
|
||||
placeholder.html(t.html('inspector.none'));
|
||||
placeholder.call(t.append('inspector.none'));
|
||||
} else {
|
||||
placeholder.html(selection.attr('value'));
|
||||
placeholder.text(selection.attr('value'));
|
||||
_oldType[selection.datum()] = tags[selection.datum()];
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
distControlEnter
|
||||
.append('span')
|
||||
.attr('class', 'restriction-control-label restriction-distance-label')
|
||||
.html(t.html('restriction.controls.distance') + ':');
|
||||
.call(t.append('restriction.controls.distance', { suffix: ':' }));
|
||||
|
||||
distControlEnter
|
||||
.append('input')
|
||||
@@ -151,7 +151,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
});
|
||||
|
||||
selection.selectAll('.restriction-distance-text')
|
||||
.html(displayMaxDistance(_maxDistance));
|
||||
.call(displayMaxDistance(_maxDistance));
|
||||
|
||||
|
||||
var viaControl = selection.selectAll('.restriction-via-way')
|
||||
@@ -167,7 +167,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
viaControlEnter
|
||||
.append('span')
|
||||
.attr('class', 'restriction-control-label restriction-via-way-label')
|
||||
.html(t.html('restriction.controls.via') + ':');
|
||||
.call(t.append('restriction.controls.via', { suffix: ':' }));
|
||||
|
||||
viaControlEnter
|
||||
.append('input')
|
||||
@@ -193,7 +193,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
});
|
||||
|
||||
selection.selectAll('.restriction-via-way-text')
|
||||
.html(displayMaxVia(_maxViaWay));
|
||||
.call(displayMaxVia(_maxViaWay));
|
||||
}
|
||||
|
||||
|
||||
@@ -463,7 +463,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
|
||||
var placeholders = {};
|
||||
['from', 'via', 'to'].forEach(function(k) {
|
||||
placeholders[k] = '<span class="qualifier">' + t('restriction.help.' + k) + '</span>';
|
||||
placeholders[k] = { html: '<span class="qualifier">' + t('restriction.help.' + k) + '</span>' };
|
||||
});
|
||||
|
||||
var entity = datum && datum.properties && datum.properties.entity;
|
||||
@@ -553,7 +553,7 @@ export function uiFieldRestrictions(field, context) {
|
||||
if (!indirect) {
|
||||
help
|
||||
.append('div') // Click for "No Right Turn"
|
||||
.html(t.html('restriction.help.toggle', { turn: nextText.trim() }));
|
||||
.html(t.html('restriction.help.toggle', { turn: { html: nextText.trim() } }));
|
||||
}
|
||||
|
||||
highlightPathsFrom(null);
|
||||
@@ -589,26 +589,33 @@ export function uiFieldRestrictions(field, context) {
|
||||
|
||||
|
||||
function displayMaxDistance(maxDist) {
|
||||
var isImperial = !localizer.usesMetric();
|
||||
var opts;
|
||||
return selection => {
|
||||
var isImperial = !localizer.usesMetric();
|
||||
var opts;
|
||||
|
||||
if (isImperial) {
|
||||
var distToFeet = { // imprecise conversion for prettier display
|
||||
20: 70, 25: 85, 30: 100, 35: 115, 40: 130, 45: 145, 50: 160
|
||||
}[maxDist];
|
||||
opts = { distance: t('units.feet', { quantity: distToFeet }) };
|
||||
} else {
|
||||
opts = { distance: t('units.meters', { quantity: maxDist }) };
|
||||
}
|
||||
if (isImperial) {
|
||||
var distToFeet = { // imprecise conversion for prettier display
|
||||
20: 70, 25: 85, 30: 100, 35: 115, 40: 130, 45: 145, 50: 160
|
||||
}[maxDist];
|
||||
opts = { distance: t('units.feet', { quantity: distToFeet }) };
|
||||
} else {
|
||||
opts = { distance: t('units.meters', { quantity: maxDist }) };
|
||||
}
|
||||
|
||||
return t.html('restriction.controls.distance_up_to', opts);
|
||||
return selection
|
||||
.html('')
|
||||
.call(t.append('restriction.controls.distance_up_to', opts));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function displayMaxVia(maxVia) {
|
||||
return maxVia === 0 ? t.html('restriction.controls.via_node_only')
|
||||
: maxVia === 1 ? t.html('restriction.controls.via_up_to_one')
|
||||
: t.html('restriction.controls.via_up_to_two');
|
||||
return selection => {
|
||||
selection = selection.html('');
|
||||
return maxVia === 0 ? selection.call(t.append('restriction.controls.via_node_only'))
|
||||
: maxVia === 1 ? selection.call(t.append('restriction.controls.via_up_to_one'))
|
||||
: selection.call(t.append('restriction.controls.via_up_to_two'));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ export function uiFormFields(context) {
|
||||
|
||||
moreEnter
|
||||
.append('span')
|
||||
.html(t.html('inspector.add_fields'));
|
||||
.call(t.append('inspector.add_fields'));
|
||||
|
||||
more = moreEnter
|
||||
.merge(more);
|
||||
|
||||
@@ -55,7 +55,7 @@ export function uiImproveOsmComments() {
|
||||
.attr('target', '_blank');
|
||||
}
|
||||
selection
|
||||
.html(d => d.username);
|
||||
.text(d => d.username);
|
||||
});
|
||||
|
||||
metadataEnter
|
||||
@@ -67,7 +67,7 @@ export function uiImproveOsmComments() {
|
||||
.append('div')
|
||||
.attr('class', 'comment-text')
|
||||
.append('p')
|
||||
.html(d => d.text);
|
||||
.text(d => d.text);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err); // eslint-disable-line no-console
|
||||
|
||||
@@ -42,12 +42,12 @@ export function uiImproveOsmDetails(context) {
|
||||
|
||||
descriptionEnter
|
||||
.append('h4')
|
||||
.html(t.html('QA.keepRight.detail_description'));
|
||||
.call(t.append('QA.keepRight.detail_description'));
|
||||
|
||||
descriptionEnter
|
||||
.append('div')
|
||||
.attr('class', 'qa-details-description-text')
|
||||
.html(issueDetail);
|
||||
.text(issueDetail);
|
||||
|
||||
// If there are entity links in the error message..
|
||||
let relatedEntities = [];
|
||||
|
||||
@@ -37,7 +37,7 @@ export function uiImproveOsmEditor(context) {
|
||||
|
||||
headerEnter
|
||||
.append('h2')
|
||||
.html(t.html('QA.improveOSM.title'));
|
||||
.call(t.append('QA.improveOSM.title'));
|
||||
|
||||
let body = selection.selectAll('.body')
|
||||
.data([0]);
|
||||
@@ -81,7 +81,7 @@ export function uiImproveOsmEditor(context) {
|
||||
saveSectionEnter
|
||||
.append('h4')
|
||||
.attr('class', '.qa-save-header')
|
||||
.html(t.html('note.newComment'));
|
||||
.call(t.append('note.newComment'));
|
||||
|
||||
saveSectionEnter
|
||||
.append('textarea')
|
||||
@@ -136,7 +136,7 @@ export function uiImproveOsmEditor(context) {
|
||||
buttonEnter
|
||||
.append('button')
|
||||
.attr('class', 'button comment-button action')
|
||||
.html(t.html('QA.keepRight.save_comment'));
|
||||
.call(t.append('QA.keepRight.save_comment'));
|
||||
|
||||
buttonEnter
|
||||
.append('button')
|
||||
|
||||
@@ -62,7 +62,7 @@ export function uiImproveOsmHeader() {
|
||||
headerEnter
|
||||
.append('div')
|
||||
.attr('class', 'qa-header-label')
|
||||
.html(issueTitle);
|
||||
.text(issueTitle);
|
||||
}
|
||||
|
||||
improveOsmHeader.issue = function(val) {
|
||||
|
||||
@@ -146,6 +146,9 @@ export function helpHtml(id, replacements) {
|
||||
help: t.html('help.title'),
|
||||
ok: t.html('intro.ok')
|
||||
};
|
||||
for (var key in helpStringReplacements) {
|
||||
helpStringReplacements[key] = { html: helpStringReplacements[key] };
|
||||
}
|
||||
}
|
||||
|
||||
var reps;
|
||||
|
||||
@@ -355,7 +355,7 @@ export function uiIntroNavigation(context, reveal) {
|
||||
var href = d3_select(selector).attr('href') || '#iD-icon-close';
|
||||
|
||||
reveal('.entity-editor-pane',
|
||||
helpHtml('intro.navigation.close_townhall', { button: icon(href, 'inline') })
|
||||
helpHtml('intro.navigation.close_townhall', { button: { html: icon(href, 'inline') } })
|
||||
);
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
@@ -368,7 +368,7 @@ export function uiIntroNavigation(context, reveal) {
|
||||
var href = d3_select(selector).attr('href') || '#iD-icon-close';
|
||||
|
||||
reveal('.entity-editor-pane',
|
||||
helpHtml('intro.navigation.close_townhall', { button: icon(href, 'inline') }),
|
||||
helpHtml('intro.navigation.close_townhall', { button: { html: icon(href, 'inline') } }),
|
||||
{ duration: 0 }
|
||||
);
|
||||
});
|
||||
@@ -492,9 +492,9 @@ export function uiIntroNavigation(context, reveal) {
|
||||
|
||||
reveal('.entity-editor-pane', helpHtml('intro.navigation.street_different_fields') + '{br}' +
|
||||
helpHtml('intro.navigation.editor_street', {
|
||||
button: icon(href, 'inline'),
|
||||
field1: onewayField.label(),
|
||||
field2: maxspeedField.label()
|
||||
button: { html: icon(href, 'inline') },
|
||||
field1: { html: onewayField.label() },
|
||||
field2: { html: maxspeedField.label() }
|
||||
}));
|
||||
|
||||
context.on('exit.intro', function() {
|
||||
@@ -508,9 +508,9 @@ export function uiIntroNavigation(context, reveal) {
|
||||
|
||||
reveal('.entity-editor-pane', helpHtml('intro.navigation.street_different_fields') + '{br}' +
|
||||
helpHtml('intro.navigation.editor_street', {
|
||||
button: icon(href, 'inline'),
|
||||
field1: onewayField.label(),
|
||||
field2: maxspeedField.label()
|
||||
button: { html: icon(href, 'inline') },
|
||||
field1: { html: onewayField.label() },
|
||||
field2: { html: maxspeedField.label() }
|
||||
}), { duration: 0 }
|
||||
);
|
||||
});
|
||||
|
||||
@@ -72,7 +72,7 @@ export function uiIntroStartEditing(context, reveal) {
|
||||
|
||||
startbutton
|
||||
.append('h2')
|
||||
.html(t.html('intro.startediting.start'));
|
||||
.call(t.append('intro.startediting.start'));
|
||||
|
||||
dispatch.call('startEditing');
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ export function uiIssuesInfo(context) {
|
||||
|
||||
enter.merge(chips)
|
||||
.selectAll('span.count')
|
||||
.html(function(d) {
|
||||
.text(function(d) {
|
||||
return d.count.toString();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ export function uiKeepRightDetails(context) {
|
||||
|
||||
descriptionEnter
|
||||
.append('h4')
|
||||
.html(t.html('QA.keepRight.detail_description'));
|
||||
.call(t.append('QA.keepRight.detail_description'));
|
||||
|
||||
descriptionEnter
|
||||
.append('div')
|
||||
|
||||
@@ -36,7 +36,7 @@ export function uiKeepRightEditor(context) {
|
||||
|
||||
headerEnter
|
||||
.append('h2')
|
||||
.html(t.html('QA.keepRight.title'));
|
||||
.call(t.append('QA.keepRight.title'));
|
||||
|
||||
|
||||
let body = selection.selectAll('.body')
|
||||
@@ -91,7 +91,7 @@ export function uiKeepRightEditor(context) {
|
||||
saveSectionEnter
|
||||
.append('h4')
|
||||
.attr('class', '.qa-save-header')
|
||||
.html(t.html('QA.keepRight.comment'));
|
||||
.call(t.append('QA.keepRight.comment'));
|
||||
|
||||
saveSectionEnter
|
||||
.append('textarea')
|
||||
@@ -147,7 +147,7 @@ export function uiKeepRightEditor(context) {
|
||||
buttonEnter
|
||||
.append('button')
|
||||
.attr('class', 'button comment-button action')
|
||||
.html(t.html('QA.keepRight.save_comment'));
|
||||
.call(t.append('QA.keepRight.save_comment'));
|
||||
|
||||
buttonEnter
|
||||
.append('button')
|
||||
|
||||
@@ -53,15 +53,18 @@ export function uiNoteComments() {
|
||||
.attr('href', osm.userURL(d.user))
|
||||
.attr('target', '_blank');
|
||||
}
|
||||
selection
|
||||
.html(function(d) { return d.user || t.html('note.anonymous'); });
|
||||
if (d.user) {
|
||||
selection.text(d.user);
|
||||
} else {
|
||||
selection.call(t.append('note.anonymous'));
|
||||
}
|
||||
});
|
||||
|
||||
metadataEnter
|
||||
.append('div')
|
||||
.attr('class', 'comment-date')
|
||||
.html(function(d) {
|
||||
return t('note.status.' + d.action, { when: localeDateString(d.date) });
|
||||
return t.html('note.status.' + d.action, { when: localeDateString(d.date) });
|
||||
});
|
||||
|
||||
mainEnter
|
||||
|
||||
+11
-11
@@ -54,7 +54,7 @@ export function uiNoteEditor(context) {
|
||||
|
||||
headerEnter
|
||||
.append('h2')
|
||||
.html(t.html('note.title'));
|
||||
.call(t.append('note.title'));
|
||||
|
||||
|
||||
var body = selection.selectAll('.body')
|
||||
@@ -149,7 +149,7 @@ export function uiNoteEditor(context) {
|
||||
.append('h4')
|
||||
.attr('class', '.note-save-header')
|
||||
.html(function() {
|
||||
return _note.isNew() ? t('note.newDescription') : t('note.newComment');
|
||||
return _note.isNew() ? t.html('note.newDescription') : t.html('note.newComment');
|
||||
});
|
||||
|
||||
var commentTextarea = noteSaveEnter
|
||||
@@ -257,14 +257,14 @@ export function uiNoteEditor(context) {
|
||||
|
||||
authEnter
|
||||
.append('span')
|
||||
.html(t.html('note.login'));
|
||||
.call(t.append('note.login'));
|
||||
|
||||
authEnter
|
||||
.append('a')
|
||||
.attr('target', '_blank')
|
||||
.call(svgIcon('#iD-icon-out-link', 'inline'))
|
||||
.append('span')
|
||||
.html(t.html('login'))
|
||||
.call(t.append('login'))
|
||||
.on('click.note-login', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
osm.authenticate();
|
||||
@@ -285,7 +285,7 @@ export function uiNoteEditor(context) {
|
||||
prose = prose.enter()
|
||||
.append('p')
|
||||
.attr('class', 'note-save-prose')
|
||||
.html(t.html('note.upload_explanation'))
|
||||
.call(t.append('note.upload_explanation'))
|
||||
.merge(prose);
|
||||
|
||||
osm.userDetails(function(err, user) {
|
||||
@@ -303,12 +303,12 @@ export function uiNoteEditor(context) {
|
||||
userLink
|
||||
.append('a')
|
||||
.attr('class', 'user-info')
|
||||
.html(user.display_name)
|
||||
.text(user.display_name)
|
||||
.attr('href', osm.userURL(user.display_name))
|
||||
.attr('target', '_blank');
|
||||
|
||||
prose
|
||||
.html(t.html('note.upload_explanation_with_user', { user: userLink.html() }));
|
||||
.html(t.html('note.upload_explanation_with_user', { user: { html: userLink.html() } }));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -334,12 +334,12 @@ export function uiNoteEditor(context) {
|
||||
buttonEnter
|
||||
.append('button')
|
||||
.attr('class', 'button cancel-button secondary-action')
|
||||
.html(t.html('confirm.cancel'));
|
||||
.call(t.append('confirm.cancel'));
|
||||
|
||||
buttonEnter
|
||||
.append('button')
|
||||
.attr('class', 'button save-button action')
|
||||
.html(t.html('note.save'));
|
||||
.call(t.append('note.save'));
|
||||
|
||||
} else {
|
||||
buttonEnter
|
||||
@@ -349,7 +349,7 @@ export function uiNoteEditor(context) {
|
||||
buttonEnter
|
||||
.append('button')
|
||||
.attr('class', 'button comment-button action')
|
||||
.html(t.html('note.comment'));
|
||||
.call(t.append('note.comment'));
|
||||
}
|
||||
|
||||
|
||||
@@ -369,7 +369,7 @@ export function uiNoteEditor(context) {
|
||||
.html(function(d) {
|
||||
var action = (d.status === 'open' ? 'close' : 'open');
|
||||
var andComment = (d.newComment ? '_comment' : '');
|
||||
return t('note.' + action + andComment);
|
||||
return t.html('note.' + action + andComment);
|
||||
})
|
||||
.on('click.status', clickStatus);
|
||||
|
||||
|
||||
@@ -50,9 +50,9 @@ export function uiNoteHeader() {
|
||||
.append('div')
|
||||
.attr('class', 'note-header-label')
|
||||
.html(function(d) {
|
||||
if (_note.isNew()) { return t('note.new'); }
|
||||
return t('note.note') + ' ' + d.id + ' ' +
|
||||
(d.status === 'closed' ? t('note.closed') : '');
|
||||
if (_note.isNew()) { return t.html('note.new'); }
|
||||
return t.html('note.note') + ' ' + d.id + ' ' +
|
||||
(d.status === 'closed' ? t.html('note.closed') : '');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ export function uiNoteReport() {
|
||||
|
||||
linkEnter
|
||||
.append('span')
|
||||
.html(t.html('note.report'));
|
||||
.call(t.append('note.report'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ export function uiNotice(context) {
|
||||
.call(svgIcon('#iD-icon-plus', 'pre-text'))
|
||||
.append('span')
|
||||
.attr('class', 'label')
|
||||
.html(t.html('zoom_in_edit'));
|
||||
.call(t.append('zoom_in_edit'));
|
||||
|
||||
|
||||
function disableTooHigh() {
|
||||
|
||||
@@ -44,7 +44,7 @@ export function uiOsmoseDetails(context) {
|
||||
|
||||
div
|
||||
.append('h4')
|
||||
.html(t.html('QA.keepRight.detail_description'));
|
||||
.call(t.append('QA.keepRight.detail_description'));
|
||||
|
||||
div
|
||||
.append('p')
|
||||
@@ -72,7 +72,7 @@ export function uiOsmoseDetails(context) {
|
||||
|
||||
div
|
||||
.append('h4')
|
||||
.html(t.html('QA.osmose.fix_title'));
|
||||
.call(t.append('QA.osmose.fix_title'));
|
||||
|
||||
div
|
||||
.append('p')
|
||||
@@ -90,7 +90,7 @@ export function uiOsmoseDetails(context) {
|
||||
|
||||
div
|
||||
.append('h4')
|
||||
.html(t.html('QA.osmose.trap_title'));
|
||||
.call(t.append('QA.osmose.trap_title'));
|
||||
|
||||
div
|
||||
.append('p')
|
||||
@@ -117,7 +117,7 @@ export function uiOsmoseDetails(context) {
|
||||
if (d.detail) {
|
||||
detailsDiv
|
||||
.append('h4')
|
||||
.html(t.html('QA.osmose.detail_title'));
|
||||
.call(t.append('QA.osmose.detail_title'));
|
||||
|
||||
detailsDiv
|
||||
.append('p')
|
||||
@@ -130,7 +130,7 @@ export function uiOsmoseDetails(context) {
|
||||
// Create list of linked issue elements
|
||||
elemsDiv
|
||||
.append('h4')
|
||||
.html(t.html('QA.osmose.elems_title'));
|
||||
.call(t.append('QA.osmose.elems_title'));
|
||||
|
||||
elemsDiv
|
||||
.append('ul').selectAll('li')
|
||||
@@ -140,7 +140,7 @@ export function uiOsmoseDetails(context) {
|
||||
.append('a')
|
||||
.attr('href', '#')
|
||||
.attr('class', 'error_entity_link')
|
||||
.html(d => d)
|
||||
.text(d => d)
|
||||
.each(function() {
|
||||
const link = d3_select(this);
|
||||
const entityID = this.textContent;
|
||||
|
||||
@@ -36,7 +36,7 @@ export function uiOsmoseEditor(context) {
|
||||
|
||||
headerEnter
|
||||
.append('h2')
|
||||
.html(t.html('QA.osmose.title'));
|
||||
.call(t.append('QA.osmose.title'));
|
||||
|
||||
let body = selection.selectAll('.body')
|
||||
.data([0]);
|
||||
@@ -118,7 +118,7 @@ export function uiOsmoseEditor(context) {
|
||||
.merge(buttonEnter);
|
||||
|
||||
buttonSection.select('.close-button')
|
||||
.html(t.html('QA.keepRight.close'))
|
||||
.call(t.append('QA.keepRight.close'))
|
||||
.on('click.close', function(d3_event, d) {
|
||||
this.blur(); // avoid keeping focus on the button - #4641
|
||||
const qaService = services.osmose;
|
||||
@@ -129,7 +129,7 @@ export function uiOsmoseEditor(context) {
|
||||
});
|
||||
|
||||
buttonSection.select('.ignore-button')
|
||||
.html(t.html('QA.keepRight.ignore'))
|
||||
.call(t.append('QA.keepRight.ignore'))
|
||||
.on('click.ignore', function(d3_event, d) {
|
||||
this.blur(); // avoid keeping focus on the button - #4641
|
||||
const qaService = services.osmose;
|
||||
|
||||
@@ -65,7 +65,7 @@ export function uiOsmoseHeader() {
|
||||
headerEnter
|
||||
.append('div')
|
||||
.attr('class', 'qa-header-label')
|
||||
.html(issueTitle);
|
||||
.text(issueTitle);
|
||||
}
|
||||
|
||||
osmoseHeader.issue = function(val) {
|
||||
|
||||
@@ -43,10 +43,10 @@ export function uiPanelBackground(context) {
|
||||
.append('li')
|
||||
.attr('class', 'background-info-list-' + k)
|
||||
.classed('hide', !_metadata[k])
|
||||
.html(t.html('info_panels.background.' + k) + ':')
|
||||
.call(t.append('info_panels.background.' + k, { suffix: ':' }))
|
||||
.append('span')
|
||||
.attr('class', 'background-info-span-' + k)
|
||||
.html(_metadata[k]);
|
||||
.text(_metadata[k]);
|
||||
});
|
||||
|
||||
debouncedGetMetadata(selection);
|
||||
@@ -55,7 +55,7 @@ export function uiPanelBackground(context) {
|
||||
|
||||
selection
|
||||
.append('a')
|
||||
.html(t.html('info_panels.background.' + toggleTiles))
|
||||
.call(t.append('info_panels.background.' + toggleTiles))
|
||||
.attr('href', '#')
|
||||
.attr('class', 'button button-toggle-tiles')
|
||||
.on('click', function(d3_event) {
|
||||
@@ -71,7 +71,7 @@ export function uiPanelBackground(context) {
|
||||
var toggleVintage = showsVintage ? 'hide_vintage' : 'show_vintage';
|
||||
selection
|
||||
.append('a')
|
||||
.html(t.html('info_panels.background.' + toggleVintage))
|
||||
.call(t.append('info_panels.background.' + toggleVintage))
|
||||
.attr('href', '#')
|
||||
.attr('class', 'button button-toggle-vintage')
|
||||
.on('click', function(d3_event) {
|
||||
@@ -110,7 +110,7 @@ export function uiPanelBackground(context) {
|
||||
selection.selectAll('.background-info-list-zoom')
|
||||
.classed('hide', false)
|
||||
.selectAll('.background-info-span-zoom')
|
||||
.html(_metadata.zoom);
|
||||
.text(_metadata.zoom);
|
||||
|
||||
if (!d || !d.length >= 3) return;
|
||||
|
||||
@@ -123,7 +123,7 @@ export function uiPanelBackground(context) {
|
||||
selection.selectAll('.background-info-list-vintage')
|
||||
.classed('hide', false)
|
||||
.selectAll('.background-info-span-vintage')
|
||||
.html(_metadata.vintage);
|
||||
.text(_metadata.vintage);
|
||||
|
||||
// update other _metadata
|
||||
_metadataKeys.forEach(function(k) {
|
||||
@@ -133,7 +133,7 @@ export function uiPanelBackground(context) {
|
||||
selection.selectAll('.background-info-list-' + k)
|
||||
.classed('hide', !val)
|
||||
.selectAll('.background-info-span-' + k)
|
||||
.html(val);
|
||||
.text(val);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -21,14 +21,14 @@ export function uiPanelHistory(context) {
|
||||
if (!userName) {
|
||||
selection
|
||||
.append('span')
|
||||
.html(t.html('info_panels.history.unknown'));
|
||||
.call(t.append('info_panels.history.unknown'));
|
||||
return;
|
||||
}
|
||||
|
||||
selection
|
||||
.append('span')
|
||||
.attr('class', 'user-name')
|
||||
.html(userName);
|
||||
.text(userName);
|
||||
|
||||
var links = selection
|
||||
.append('div')
|
||||
@@ -40,7 +40,7 @@ export function uiPanelHistory(context) {
|
||||
.attr('class', 'user-osm-link')
|
||||
.attr('href', osm.userURL(userName))
|
||||
.attr('target', '_blank')
|
||||
.html('OSM');
|
||||
.call(t.append('info_panels.history.profile_link'));
|
||||
}
|
||||
|
||||
links
|
||||
@@ -49,7 +49,7 @@ export function uiPanelHistory(context) {
|
||||
.attr('href', 'https://hdyc.neis-one.org/?' + userName)
|
||||
.attr('target', '_blank')
|
||||
.attr('tabindex', -1)
|
||||
.html('HDYC');
|
||||
.text('HDYC');
|
||||
}
|
||||
|
||||
|
||||
@@ -57,14 +57,14 @@ export function uiPanelHistory(context) {
|
||||
if (!changeset) {
|
||||
selection
|
||||
.append('span')
|
||||
.html(t.html('info_panels.history.unknown'));
|
||||
.call(t.append('info_panels.history.unknown'));
|
||||
return;
|
||||
}
|
||||
|
||||
selection
|
||||
.append('span')
|
||||
.attr('class', 'changeset-id')
|
||||
.html(changeset);
|
||||
.text(changeset);
|
||||
|
||||
var links = selection
|
||||
.append('div')
|
||||
@@ -76,7 +76,7 @@ export function uiPanelHistory(context) {
|
||||
.attr('class', 'changeset-osm-link')
|
||||
.attr('href', osm.changesetURL(changeset))
|
||||
.attr('target', '_blank')
|
||||
.html('OSM');
|
||||
.call(t.append('info_panels.history.changeset_link'));
|
||||
}
|
||||
|
||||
links
|
||||
@@ -84,24 +84,23 @@ export function uiPanelHistory(context) {
|
||||
.attr('class', 'changeset-osmcha-link')
|
||||
.attr('href', 'https://osmcha.org/changesets/' + changeset)
|
||||
.attr('target', '_blank')
|
||||
.html('OSMCha');
|
||||
.text('OSMCha');
|
||||
|
||||
links
|
||||
.append('a')
|
||||
.attr('class', 'changeset-achavi-link')
|
||||
.attr('href', 'https://overpass-api.de/achavi/?changeset=' + changeset)
|
||||
.attr('target', '_blank')
|
||||
.html('Achavi');
|
||||
.text('Achavi');
|
||||
}
|
||||
|
||||
|
||||
function redraw(selection) {
|
||||
var selectedNoteID = context.selectedNoteID();
|
||||
osm = context.connection();
|
||||
|
||||
var selected, note, entity;
|
||||
if (selectedNoteID && osm) { // selected 1 note
|
||||
selected = [ t('note.note') + ' ' + selectedNoteID ];
|
||||
selected = [ t.html('note.note') + ' ' + selectedNoteID ];
|
||||
note = osm.getNote(selectedNoteID);
|
||||
} else { // selected 1..n entities
|
||||
selected = context.selectedIDs()
|
||||
@@ -115,10 +114,17 @@ export function uiPanelHistory(context) {
|
||||
|
||||
selection.html('');
|
||||
|
||||
selection
|
||||
.append('h4')
|
||||
.attr('class', 'history-heading')
|
||||
.html(singular || t.html('info_panels.selected', { n: selected.length }));
|
||||
if (singular) {
|
||||
selection
|
||||
.append('h4')
|
||||
.attr('class', 'history-heading')
|
||||
.html(singular);
|
||||
} else {
|
||||
selection
|
||||
.append('h4')
|
||||
.attr('class', 'history-heading')
|
||||
.call(t.append('info_panels.selected', { n: selected.length }));
|
||||
}
|
||||
|
||||
if (!singular) return;
|
||||
|
||||
@@ -134,7 +140,7 @@ export function uiPanelHistory(context) {
|
||||
if (!note || note.isNew()) {
|
||||
selection
|
||||
.append('div')
|
||||
.html(t.html('info_panels.history.note_no_history'));
|
||||
.call(t.append('info_panels.history.note_no_history'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -143,20 +149,20 @@ export function uiPanelHistory(context) {
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.history.note_comments') + ':')
|
||||
.call(t.append('info_panels.history.note_comments', { suffix: ':' }))
|
||||
.append('span')
|
||||
.html(note.comments.length);
|
||||
.text(note.comments.length);
|
||||
|
||||
if (note.comments.length) {
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.history.note_created_date') + ':')
|
||||
.call(t.append('info_panels.history.note_created_date', { suffix: ':' }))
|
||||
.append('span')
|
||||
.html(displayTimestamp(note.comments[0].date));
|
||||
.text(displayTimestamp(note.comments[0].date));
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.history.note_created_user') + ':')
|
||||
.call(t.append('info_panels.history.note_created_user', { suffix: ':' }))
|
||||
.call(displayUser, note.comments[0].user);
|
||||
}
|
||||
|
||||
@@ -168,7 +174,7 @@ export function uiPanelHistory(context) {
|
||||
.attr('href', osm.noteURL(note))
|
||||
.call(svgIcon('#iD-icon-out-link', 'inline'))
|
||||
.append('span')
|
||||
.html(t.html('info_panels.history.note_link_text'));
|
||||
.call(t.append('info_panels.history.note_link_text'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +183,7 @@ export function uiPanelHistory(context) {
|
||||
if (!entity || entity.isNew()) {
|
||||
selection
|
||||
.append('div')
|
||||
.html(t.html('info_panels.history.no_history'));
|
||||
.call(t.append('info_panels.history.no_history'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -191,8 +197,7 @@ export function uiPanelHistory(context) {
|
||||
.attr('class', 'view-history-on-osm')
|
||||
.attr('href', osm.historyURL(entity))
|
||||
.attr('target', '_blank')
|
||||
.attr('title', t('info_panels.history.link_text'))
|
||||
.html('OSM');
|
||||
.call(t.append('info_panels.history.history_link'));
|
||||
}
|
||||
links
|
||||
.append('a')
|
||||
@@ -200,31 +205,31 @@ export function uiPanelHistory(context) {
|
||||
.attr('href', 'https://pewu.github.io/osm-history/#/' + entity.type + '/' + entity.osmId())
|
||||
.attr('target', '_blank')
|
||||
.attr('tabindex', -1)
|
||||
.html('PeWu');
|
||||
.text('PeWu');
|
||||
|
||||
var list = selection
|
||||
.append('ul');
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.history.version') + ':')
|
||||
.call(t.append('info_panels.history.version', { suffix: ':' }))
|
||||
.append('span')
|
||||
.html(entity.version);
|
||||
.text(entity.version);
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.history.last_edit') + ':')
|
||||
.call(t.append('info_panels.history.last_edit', { suffix: ':' }))
|
||||
.append('span')
|
||||
.html(displayTimestamp(entity.timestamp));
|
||||
.text(displayTimestamp(entity.timestamp));
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.history.edited_by') + ':')
|
||||
.call(t.append('info_panels.history.edited_by', { suffix: ':' }))
|
||||
.call(displayUser, entity.user);
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.history.changeset') + ':')
|
||||
.call(t.append('info_panels.history.changeset', { suffix: ':' }))
|
||||
.call(displayChangeset, entity.changeset);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,15 +23,15 @@ export function uiPanelLocation(context) {
|
||||
|
||||
list
|
||||
.append('li')
|
||||
.html(dmsCoordinatePair(coord))
|
||||
.text(dmsCoordinatePair(coord))
|
||||
.append('li')
|
||||
.html(decimalCoordinatePair(coord));
|
||||
.text(decimalCoordinatePair(coord));
|
||||
|
||||
// Location Info
|
||||
selection
|
||||
.append('div')
|
||||
.attr('class', 'location-info')
|
||||
.html(currLocation || ' ');
|
||||
.text(currLocation || ' ');
|
||||
|
||||
debouncedGetLocation(selection, coord);
|
||||
}
|
||||
@@ -42,12 +42,12 @@ export function uiPanelLocation(context) {
|
||||
if (!services.geocoder) {
|
||||
currLocation = t('info_panels.location.unknown_location');
|
||||
selection.selectAll('.location-info')
|
||||
.html(currLocation);
|
||||
.text(currLocation);
|
||||
} else {
|
||||
services.geocoder.reverse(coord, function(err, result) {
|
||||
currLocation = result ? result.display_name : t('info_panels.location.unknown_location');
|
||||
selection.selectAll('.location-info')
|
||||
.html(currLocation);
|
||||
.text(currLocation);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ export function uiPanelMeasurement(context) {
|
||||
if (selectedNoteID && osm) { // selected 1 note
|
||||
|
||||
var note = osm.getNote(selectedNoteID);
|
||||
heading = t('note.note') + ' ' + selectedNoteID;
|
||||
heading = t.html('note.note') + ' ' + selectedNoteID;
|
||||
location = note.loc;
|
||||
geometry = 'note';
|
||||
|
||||
@@ -65,7 +65,7 @@ export function uiPanelMeasurement(context) {
|
||||
});
|
||||
|
||||
heading = selected.length === 1 ? selected[0].id :
|
||||
t('info_panels.selected', { n: selected.length });
|
||||
t.html('info_panels.selected', { n: selected.length });
|
||||
|
||||
if (selected.length) {
|
||||
var extent = geoExtent();
|
||||
@@ -129,80 +129,80 @@ export function uiPanelMeasurement(context) {
|
||||
if (geometry) {
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.measurement.geometry') + ':')
|
||||
.call(t.append('info_panels.measurement.geometry', { suffix: ':' }))
|
||||
.append('span')
|
||||
.html(
|
||||
closed ? t('info_panels.measurement.closed_' + geometry) : t('geometry.' + geometry)
|
||||
closed ? t.html('info_panels.measurement.closed_' + geometry) : t.html('geometry.' + geometry)
|
||||
);
|
||||
}
|
||||
|
||||
if (totalNodeCount) {
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.measurement.node_count') + ':')
|
||||
.call(t.append('info_panels.measurement.node_count', { suffix: ':' }))
|
||||
.append('span')
|
||||
.html(totalNodeCount.toLocaleString(localeCode));
|
||||
.text(totalNodeCount.toLocaleString(localeCode));
|
||||
}
|
||||
|
||||
if (area) {
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.measurement.area') + ':')
|
||||
.call(t.append('info_panels.measurement.area', { suffix: ':' }))
|
||||
.append('span')
|
||||
.html(displayArea(area, _isImperial));
|
||||
.text(displayArea(area, _isImperial));
|
||||
}
|
||||
|
||||
if (length) {
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.measurement.' + (closed ? 'perimeter' : 'length')) + ':')
|
||||
.call(t.append('info_panels.measurement.' + (closed ? 'perimeter' : 'length'), { suffix: ':' }))
|
||||
.append('span')
|
||||
.html(displayLength(length, _isImperial));
|
||||
.text(displayLength(length, _isImperial));
|
||||
}
|
||||
|
||||
if (typeof distance === 'number') {
|
||||
list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.measurement.distance') + ':')
|
||||
.call(t.append('info_panels.measurement.distance', { suffix: ':' }))
|
||||
.append('span')
|
||||
.html(displayLength(distance, _isImperial));
|
||||
.text(displayLength(distance, _isImperial));
|
||||
}
|
||||
|
||||
if (location) {
|
||||
coordItem = list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.measurement.location') + ':');
|
||||
.call(t.append('info_panels.measurement.location', { suffix: ':' }));
|
||||
coordItem.append('span')
|
||||
.html(dmsCoordinatePair(location));
|
||||
.text(dmsCoordinatePair(location));
|
||||
coordItem.append('span')
|
||||
.html(decimalCoordinatePair(location));
|
||||
.text(decimalCoordinatePair(location));
|
||||
}
|
||||
|
||||
if (centroid) {
|
||||
coordItem = list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.measurement.centroid') + ':');
|
||||
.call(t.append('info_panels.measurement.centroid', { suffix: ':' }));
|
||||
coordItem.append('span')
|
||||
.html(dmsCoordinatePair(centroid));
|
||||
.text(dmsCoordinatePair(centroid));
|
||||
coordItem.append('span')
|
||||
.html(decimalCoordinatePair(centroid));
|
||||
.text(decimalCoordinatePair(centroid));
|
||||
}
|
||||
|
||||
if (center) {
|
||||
coordItem = list
|
||||
.append('li')
|
||||
.html(t.html('info_panels.measurement.center') + ':');
|
||||
.call(t.append('info_panels.measurement.center', { suffix: ':' }));
|
||||
coordItem.append('span')
|
||||
.html(dmsCoordinatePair(center));
|
||||
.text(dmsCoordinatePair(center));
|
||||
coordItem.append('span')
|
||||
.html(decimalCoordinatePair(center));
|
||||
.text(decimalCoordinatePair(center));
|
||||
}
|
||||
|
||||
if (length || area || typeof distance === 'number') {
|
||||
var toggle = _isImperial ? 'imperial' : 'metric';
|
||||
selection
|
||||
.append('a')
|
||||
.html(t.html('info_panels.measurement.' + toggle))
|
||||
.call(t.append('info_panels.measurement.' + toggle))
|
||||
.attr('href', '#')
|
||||
.attr('class', 'button button-toggle-units')
|
||||
.on('click', function(d3_event) {
|
||||
|
||||
@@ -383,7 +383,7 @@ export function uiPaneHelp(context) {
|
||||
|
||||
shortcuts
|
||||
.append('div')
|
||||
.html(t.html('shortcuts.title'));
|
||||
.call(t.append('shortcuts.title'));
|
||||
|
||||
var walkthrough = toc
|
||||
.append('li')
|
||||
@@ -400,7 +400,7 @@ export function uiPaneHelp(context) {
|
||||
|
||||
walkthrough
|
||||
.append('div')
|
||||
.html(t.html('splash.walkthrough'));
|
||||
.call(t.append('splash.walkthrough'));
|
||||
|
||||
|
||||
var helpContent = content
|
||||
|
||||
@@ -35,7 +35,7 @@ export function uiPresetList(context) {
|
||||
|
||||
var message = messagewrap
|
||||
.append('h2')
|
||||
.html(t.html('inspector.choose'));
|
||||
.call(t.append('inspector.choose'));
|
||||
|
||||
var direction = (localizer.textDirection() === 'rtl') ? 'backward' : 'forward';
|
||||
|
||||
@@ -99,13 +99,13 @@ export function uiPresetList(context) {
|
||||
var results, messageText;
|
||||
if (value.length) {
|
||||
results = presets.search(value, entityGeometries()[0], _currLoc);
|
||||
messageText = t('inspector.results', {
|
||||
messageText = t.html('inspector.results', {
|
||||
n: results.collection.length,
|
||||
search: value
|
||||
});
|
||||
} else {
|
||||
results = presetManager.defaults(entityGeometries()[0], 36, !context.inIntro(), _currLoc);
|
||||
messageText = t('inspector.choose');
|
||||
messageText = t.html('inspector.choose');
|
||||
}
|
||||
list.call(drawList, results);
|
||||
message.html(messageText);
|
||||
|
||||
@@ -17,13 +17,13 @@ export function uiRestore(context) {
|
||||
.append('div')
|
||||
.attr('class', 'modal-section')
|
||||
.append('h3')
|
||||
.html(t.html('restore.heading'));
|
||||
.call(t.append('restore.heading'));
|
||||
|
||||
introModal
|
||||
.append('div')
|
||||
.attr('class','modal-section')
|
||||
.append('p')
|
||||
.html(t.html('restore.description'));
|
||||
.call(t.append('restore.description'));
|
||||
|
||||
let buttonWrap = introModal
|
||||
.append('div')
|
||||
@@ -45,7 +45,7 @@ export function uiRestore(context) {
|
||||
|
||||
restore
|
||||
.append('div')
|
||||
.html(t.html('restore.restore'));
|
||||
.call(t.append('restore.restore'));
|
||||
|
||||
let reset = buttonWrap
|
||||
.append('button')
|
||||
@@ -63,7 +63,7 @@ export function uiRestore(context) {
|
||||
|
||||
reset
|
||||
.append('div')
|
||||
.html(t.html('restore.reset'));
|
||||
.call(t.append('restore.reset'));
|
||||
|
||||
restore.node().focus();
|
||||
};
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ export function uiScale(context) {
|
||||
|
||||
selection.select('.scale-text')
|
||||
.style(localizer.textDirection() === 'ltr' ? 'left' : 'right', (scale.px + 16) + 'px')
|
||||
.html(scale.text);
|
||||
.text(scale.text);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ export function uiSectionBackgroundDisplayOptions(context) {
|
||||
.attr('class', 'display-option-resetlink')
|
||||
.attr('role', 'button')
|
||||
.attr('href', '#')
|
||||
.html(t.html('background.reset_all'))
|
||||
.call(t.append('background.reset_all'))
|
||||
.on('click', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
for (var i = 0; i < _sliders.length; i++) {
|
||||
@@ -119,7 +119,7 @@ export function uiSectionBackgroundDisplayOptions(context) {
|
||||
.property('value', function(d) { return _options[d]; });
|
||||
|
||||
container.selectAll('.display-option-value')
|
||||
.html(function(d) { return Math.floor(_options[d] * 100) + '%'; });
|
||||
.text(function(d) { return Math.floor(_options[d] * 100) + '%'; });
|
||||
|
||||
container.selectAll('.display-option-reset')
|
||||
.classed('disabled', function(d) { return _options[d] === 1; });
|
||||
|
||||
@@ -70,7 +70,7 @@ export function uiSectionBackgroundList(context) {
|
||||
|
||||
minimapLabelEnter
|
||||
.append('span')
|
||||
.html(t.html('background.minimap.description'));
|
||||
.call(t.append('background.minimap.description'));
|
||||
|
||||
|
||||
var panelLabelEnter = bgExtrasListEnter
|
||||
@@ -93,7 +93,7 @@ export function uiSectionBackgroundList(context) {
|
||||
|
||||
panelLabelEnter
|
||||
.append('span')
|
||||
.html(t.html('background.panel.description'));
|
||||
.call(t.append('background.panel.description'));
|
||||
|
||||
var locPanelLabelEnter = bgExtrasListEnter
|
||||
.append('li')
|
||||
@@ -115,7 +115,7 @@ export function uiSectionBackgroundList(context) {
|
||||
|
||||
locPanelLabelEnter
|
||||
.append('span')
|
||||
.html(t.html('background.location_panel.description'));
|
||||
.call(t.append('background.location_panel.description'));
|
||||
|
||||
|
||||
// "Info / Report a Problem" link
|
||||
@@ -129,7 +129,7 @@ export function uiSectionBackgroundList(context) {
|
||||
.call(svgIcon('#iD-icon-out-link', 'inline'))
|
||||
.attr('href', 'https://github.com/openstreetmap/iD/blob/develop/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
|
||||
.append('span')
|
||||
.html(t.html('background.imagery_problem_faq'));
|
||||
.call(t.append('background.imagery_problem_faq'));
|
||||
|
||||
_backgroundList
|
||||
.call(drawListItems, 'radio', function(d3_event, d) {
|
||||
|
||||
@@ -132,7 +132,7 @@ export function uiSectionBackgroundOffset(context) {
|
||||
containerEnter
|
||||
.append('div')
|
||||
.attr('class', 'nudge-instructions')
|
||||
.html(t.html('background.offset'));
|
||||
.call(t.append('background.offset'));
|
||||
|
||||
var nudgeWrapEnter = containerEnter
|
||||
.append('div')
|
||||
|
||||
@@ -29,7 +29,7 @@ export function uiSectionChanges(context) {
|
||||
.label(function() {
|
||||
var history = context.history();
|
||||
var summary = history.difference().summary();
|
||||
return t('inspector.title_count', { title: t.html('commit.changes'), count: summary.length });
|
||||
return t.html('inspector.title_count', { title: { html: t.html('commit.changes') }, count: summary.length });
|
||||
})
|
||||
.disclosureContent(renderDisclosureContent);
|
||||
|
||||
@@ -79,7 +79,7 @@ export function uiSectionChanges(context) {
|
||||
buttons
|
||||
.append('strong')
|
||||
.attr('class', 'entity-type')
|
||||
.html(function(d) {
|
||||
.text(function(d) {
|
||||
var matched = presetManager.match(d.entity, d.graph);
|
||||
return (matched && matched.name()) || utilDisplayType(d.entity.id);
|
||||
});
|
||||
@@ -87,7 +87,7 @@ export function uiSectionChanges(context) {
|
||||
buttons
|
||||
.append('span')
|
||||
.attr('class', 'entity-name')
|
||||
.html(function(d) {
|
||||
.text(function(d) {
|
||||
var name = utilDisplayName(d.entity) || '',
|
||||
string = '';
|
||||
if (name !== '') {
|
||||
@@ -132,7 +132,7 @@ export function uiSectionChanges(context) {
|
||||
linkEnter
|
||||
.call(svgIcon('#iD-icon-load', 'inline'))
|
||||
.append('span')
|
||||
.html(t.html('commit.download_changes'));
|
||||
.call(t.append('commit.download_changes'));
|
||||
|
||||
|
||||
function mouseover(d) {
|
||||
|
||||
@@ -217,7 +217,7 @@ export function uiSectionDataLayers(context) {
|
||||
containerEnter
|
||||
.append('h4')
|
||||
.attr('class', 'vectortile-header')
|
||||
.html('Detroit Vector Tiles (Beta)');
|
||||
.text('Detroit Vector Tiles (Beta)');
|
||||
|
||||
containerEnter
|
||||
.append('ul')
|
||||
@@ -231,7 +231,7 @@ export function uiSectionDataLayers(context) {
|
||||
.call(svgIcon('#iD-icon-out-link', 'inline'))
|
||||
.attr('href', 'https://github.com/osmus/detroit-mapping-challenge')
|
||||
.append('span')
|
||||
.html('About these layers');
|
||||
.text('About these layers');
|
||||
|
||||
container = container
|
||||
.merge(containerEnter);
|
||||
@@ -265,7 +265,7 @@ export function uiSectionDataLayers(context) {
|
||||
|
||||
labelEnter
|
||||
.append('span')
|
||||
.html(function(d) { return d.name; });
|
||||
.text(function(d) { return d.name; });
|
||||
|
||||
// Update
|
||||
li
|
||||
@@ -324,7 +324,7 @@ export function uiSectionDataLayers(context) {
|
||||
|
||||
labelEnter
|
||||
.append('span')
|
||||
.html(t.html('map_data.layers.custom.title'));
|
||||
.call(t.append('map_data.layers.custom.title'));
|
||||
|
||||
liEnter
|
||||
.append('button')
|
||||
@@ -415,7 +415,7 @@ export function uiSectionDataLayers(context) {
|
||||
|
||||
historyPanelLabelEnter
|
||||
.append('span')
|
||||
.html(t.html('map_data.history_panel.title'));
|
||||
.call(t.append('map_data.history_panel.title'));
|
||||
|
||||
var measurementPanelLabelEnter = panelsListEnter
|
||||
.append('li')
|
||||
@@ -437,7 +437,7 @@ export function uiSectionDataLayers(context) {
|
||||
|
||||
measurementPanelLabelEnter
|
||||
.append('span')
|
||||
.html(t.html('map_data.measurement_panel.title'));
|
||||
.call(t.append('map_data.measurement_panel.title'));
|
||||
}
|
||||
|
||||
context.layers().on('change.uiSectionDataLayers', section.reRender);
|
||||
|
||||
@@ -24,7 +24,7 @@ export function uiSectionEntityIssues(context) {
|
||||
return _issues.length > 0;
|
||||
})
|
||||
.label(function() {
|
||||
return t('inspector.title_count', { title: t.html('issues.list_title'), count: _issues.length });
|
||||
return t.html('inspector.title_count', { title: { html: t.html('issues.list_title') }, count: _issues.length });
|
||||
})
|
||||
.disclosureContent(renderDisclosureContent);
|
||||
|
||||
@@ -169,7 +169,7 @@ export function uiSectionEntityIssues(context) {
|
||||
.call(d.reference);
|
||||
} else {
|
||||
d3_select(this)
|
||||
.html(t.html('inspector.no_documentation_key'));
|
||||
.call(t.append('inspector.no_documentation_key'));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ export function uiSectionMapFeatures(context) {
|
||||
.attr('class', 'feature-list-link')
|
||||
.attr('role', 'button')
|
||||
.attr('href', '#')
|
||||
.html(t.html('issues.disable_all'))
|
||||
.call(t.append('issues.disable_all'))
|
||||
.on('click', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
context.features().disableAll();
|
||||
@@ -44,7 +44,7 @@ export function uiSectionMapFeatures(context) {
|
||||
.attr('class', 'feature-list-link')
|
||||
.attr('role', 'button')
|
||||
.attr('href', '#')
|
||||
.html(t.html('issues.enable_all'))
|
||||
.call(t.append('issues.enable_all'))
|
||||
.on('click', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
context.features().enableAll();
|
||||
|
||||
@@ -273,7 +273,7 @@ export function uiSectionPhotoOverlays(context) {
|
||||
|
||||
labelEnter
|
||||
.append('span')
|
||||
.html(t.html('photo_overlays.username_filter.title'));
|
||||
.call(t.append('photo_overlays.username_filter.title'));
|
||||
|
||||
labelEnter
|
||||
.append('input')
|
||||
|
||||
@@ -5,22 +5,22 @@ import { svgIcon } from '../../svg/icon';
|
||||
import { uiSection } from '../section';
|
||||
|
||||
export function uiSectionPrivacy(context) {
|
||||
|
||||
let section = uiSection('preferences-third-party', context)
|
||||
.label(t.html('preferences.privacy.title'))
|
||||
.disclosureContent(renderDisclosureContent);
|
||||
|
||||
let _showThirdPartyIcons = prefs('preferences.privacy.thirdpartyicons') || 'true';
|
||||
|
||||
function renderDisclosureContent(selection) {
|
||||
// enter
|
||||
let privacyOptionsListEnter = selection.selectAll('.privacy-options-list')
|
||||
selection.selectAll('.privacy-options-list')
|
||||
.data([0])
|
||||
.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list privacy-options-list');
|
||||
|
||||
let thirdPartyIconsEnter = privacyOptionsListEnter
|
||||
let thirdPartyIconsEnter = selection.select('.privacy-options-list')
|
||||
.selectAll('.privacy-third-party-icons-item')
|
||||
.data([prefs('preferences.privacy.thirdpartyicons') || 'true'])
|
||||
.enter()
|
||||
.append('li')
|
||||
.attr('class', 'privacy-third-party-icons-item')
|
||||
.append('label')
|
||||
@@ -32,17 +32,20 @@ export function uiSectionPrivacy(context) {
|
||||
thirdPartyIconsEnter
|
||||
.append('input')
|
||||
.attr('type', 'checkbox')
|
||||
.on('change', (d3_event) => {
|
||||
.on('change', (d3_event, d) => {
|
||||
d3_event.preventDefault();
|
||||
_showThirdPartyIcons = (_showThirdPartyIcons === 'true') ? 'false' : 'true';
|
||||
prefs('preferences.privacy.thirdpartyicons', _showThirdPartyIcons);
|
||||
update();
|
||||
prefs('preferences.privacy.thirdpartyicons', d === 'true' ? 'false' : 'true');
|
||||
});
|
||||
|
||||
thirdPartyIconsEnter
|
||||
.append('span')
|
||||
.html(t.html('preferences.privacy.third_party_icons.description'));
|
||||
.call(t.append('preferences.privacy.third_party_icons.description'));
|
||||
|
||||
// update
|
||||
selection.selectAll('.privacy-third-party-icons-item')
|
||||
.classed('active', d => d === 'true')
|
||||
.select('input')
|
||||
.property('checked', d => d === 'true');
|
||||
|
||||
// Privacy Policy link
|
||||
selection.selectAll('.privacy-link')
|
||||
@@ -55,18 +58,11 @@ export function uiSectionPrivacy(context) {
|
||||
.call(svgIcon('#iD-icon-out-link', 'inline'))
|
||||
.attr('href', 'https://github.com/openstreetmap/iD/blob/release/PRIVACY.md')
|
||||
.append('span')
|
||||
.html(t.html('preferences.privacy.privacy_link'));
|
||||
.call(t.append('preferences.privacy.privacy_link'));
|
||||
|
||||
update();
|
||||
|
||||
|
||||
function update() {
|
||||
selection.selectAll('.privacy-third-party-icons-item')
|
||||
.classed('active', (_showThirdPartyIcons === 'true'))
|
||||
.select('input')
|
||||
.property('checked', (_showThirdPartyIcons === 'true'));
|
||||
}
|
||||
}
|
||||
|
||||
prefs.onChange('preferences.privacy.thirdpartyicons', section.reRender);
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export function uiSectionRawMemberEditor(context) {
|
||||
|
||||
var gt = entity.members.length > _maxMembers ? '>' : '';
|
||||
var count = gt + entity.members.slice(0, _maxMembers).length;
|
||||
return t('inspector.title_count', { title: t.html('inspector.members'), count: count });
|
||||
return t.html('inspector.title_count', { title: { html: t.html('inspector.members') }, count: count });
|
||||
})
|
||||
.disclosureContent(renderDisclosureContent);
|
||||
|
||||
@@ -190,7 +190,7 @@ export function uiSectionRawMemberEditor(context) {
|
||||
labelLink
|
||||
.append('span')
|
||||
.attr('class', 'member-entity-type')
|
||||
.html(function(d) {
|
||||
.text(function(d) {
|
||||
var matched = presetManager.match(d.member, context.graph());
|
||||
return (matched && matched.name()) || utilDisplayType(d.member.id);
|
||||
});
|
||||
@@ -198,7 +198,7 @@ export function uiSectionRawMemberEditor(context) {
|
||||
labelLink
|
||||
.append('span')
|
||||
.attr('class', 'member-entity-name')
|
||||
.html(function(d) { return utilDisplayName(d.member); });
|
||||
.text(function(d) { return utilDisplayName(d.member); });
|
||||
|
||||
label
|
||||
.append('button')
|
||||
@@ -221,12 +221,12 @@ export function uiSectionRawMemberEditor(context) {
|
||||
labelText
|
||||
.append('span')
|
||||
.attr('class', 'member-entity-type')
|
||||
.html(t.html('inspector.' + d.type, { id: d.id }));
|
||||
.call(t.append('inspector.' + d.type, { id: d.id }));
|
||||
|
||||
labelText
|
||||
.append('span')
|
||||
.attr('class', 'member-entity-name')
|
||||
.html(t.html('inspector.incomplete', { id: d.id }));
|
||||
.call(t.append('inspector.incomplete', { id: d.id }));
|
||||
|
||||
label
|
||||
.append('button')
|
||||
|
||||
@@ -31,7 +31,7 @@ export function uiSectionRawMembershipEditor(context) {
|
||||
var parents = getSharedParentRelations();
|
||||
var gt = parents.length > _maxMemberships ? '>' : '';
|
||||
var count = gt + parents.slice(0, _maxMemberships).length;
|
||||
return t('inspector.title_count', { title: t.html('inspector.relations'), count: count });
|
||||
return t.html('inspector.title_count', { title: { html: t.html('inspector.relations') }, count: count });
|
||||
})
|
||||
.disclosureContent(renderDisclosureContent);
|
||||
|
||||
@@ -341,15 +341,15 @@ export function uiSectionRawMembershipEditor(context) {
|
||||
labelLink
|
||||
.append('span')
|
||||
.attr('class', 'member-entity-type')
|
||||
.html(function(d) {
|
||||
.text(function(d) {
|
||||
var matched = presetManager.match(d.relation, context.graph());
|
||||
return (matched && matched.name()) || t('inspector.relation');
|
||||
return (matched && matched.name()) || t.html('inspector.relation');
|
||||
});
|
||||
|
||||
labelLink
|
||||
.append('span')
|
||||
.attr('class', 'member-entity-name')
|
||||
.html(function(d) { return utilDisplayName(d.relation); });
|
||||
.text(function(d) { return utilDisplayName(d.relation); });
|
||||
|
||||
labelEnter
|
||||
.append('button')
|
||||
|
||||
@@ -12,13 +12,14 @@ import { utilArrayDifference, utilArrayIdentical } from '../../util/array';
|
||||
import { utilGetSetValue, utilNoAuto, utilRebind, utilTagDiff } from '../../util';
|
||||
import { uiTooltip } from '..';
|
||||
|
||||
|
||||
export function uiSectionRawTagEditor(id, context) {
|
||||
|
||||
var section = uiSection(id, context)
|
||||
.classes('raw-tag-editor')
|
||||
.label(function() {
|
||||
var count = Object.keys(_tags).filter(function(d) { return d; }).length;
|
||||
return t('inspector.title_count', { title: t.html('inspector.tags'), count: count });
|
||||
return t.html('inspector.title_count', { title: { html: t.html('inspector.tags') }, count: count });
|
||||
})
|
||||
.expandedByDefault(false)
|
||||
.disclosureContent(renderDisclosureContent);
|
||||
@@ -261,7 +262,7 @@ export function uiSectionRawTagEditor(id, context) {
|
||||
.attr('title', function(d) { return d.key; })
|
||||
.call(utilGetSetValue, function(d) { return d.key; })
|
||||
.attr('readonly', function(d) {
|
||||
return (isReadOnly(d) || (typeof d.value !== 'string')) || null;
|
||||
return isReadOnly(d) || null;
|
||||
});
|
||||
|
||||
items.selectAll('input.value')
|
||||
@@ -495,27 +496,29 @@ export function uiSectionRawTagEditor(id, context) {
|
||||
}
|
||||
|
||||
|
||||
var row = this.parentNode.parentNode;
|
||||
var inputVal = d3_select(row).selectAll('input.value');
|
||||
var vNew = context.cleanTagValue(utilGetSetValue(inputVal));
|
||||
|
||||
_pendingChange = _pendingChange || {};
|
||||
|
||||
if (kOld) {
|
||||
if (kOld === kNew) return;
|
||||
// a tag key was renamed
|
||||
_pendingChange[kNew] = _pendingChange[kOld] || { oldKey: kOld };
|
||||
_pendingChange[kOld] = undefined;
|
||||
} else {
|
||||
// a new tag was added
|
||||
let row = this.parentNode.parentNode;
|
||||
let inputVal = d3_select(row).selectAll('input.value');
|
||||
let vNew = context.cleanTagValue(utilGetSetValue(inputVal));
|
||||
_pendingChange[kNew] = vNew;
|
||||
utilGetSetValue(inputVal, vNew);
|
||||
}
|
||||
|
||||
_pendingChange[kNew] = vNew;
|
||||
|
||||
// update the ordered key index so this row doesn't change position
|
||||
var existingKeyIndex = _orderedKeys.indexOf(kOld);
|
||||
if (existingKeyIndex !== -1) _orderedKeys[existingKeyIndex] = kNew;
|
||||
|
||||
d.key = kNew; // update datum to avoid exit/enter on tag update
|
||||
d.value = vNew;
|
||||
|
||||
this.value = kNew;
|
||||
utilGetSetValue(inputVal, vNew);
|
||||
scheduleChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ export function uiSectionSelectionList(context) {
|
||||
return _selectedIDs.length > 1;
|
||||
})
|
||||
.label(function() {
|
||||
return t('inspector.title_count', { title: t.html('inspector.features'), count: _selectedIDs.length });
|
||||
return t.html('inspector.title_count', { title: { html: t.html('inspector.features') }, count: _selectedIDs.length });
|
||||
})
|
||||
.disclosureContent(renderDisclosureContent);
|
||||
|
||||
@@ -116,10 +116,10 @@ export function uiSectionSelectionList(context) {
|
||||
});
|
||||
|
||||
items.selectAll('.entity-type')
|
||||
.html(function(entity) { return presetManager.match(entity, context.graph()).name(); });
|
||||
.text(function(entity) { return presetManager.match(entity, context.graph()).name(); });
|
||||
|
||||
items.selectAll('.entity-name')
|
||||
.html(function(d) {
|
||||
.text(function(d) {
|
||||
// fetch latest entity
|
||||
var entity = context.entity(d.id);
|
||||
return utilDisplayName(entity);
|
||||
|
||||
@@ -19,7 +19,7 @@ export function uiSectionValidationIssues(id, severity, context) {
|
||||
.label(function() {
|
||||
if (!_issues) return '';
|
||||
var issueCountText = _issues.length > 1000 ? '1000+' : String(_issues.length);
|
||||
return t('inspector.title_count', { title: t.html('issues.' + severity + 's.list_title'), count: issueCountText });
|
||||
return t.html('inspector.title_count', { title: { html: t.html('issues.' + severity + 's.list_title') }, count: issueCountText });
|
||||
})
|
||||
.disclosureContent(renderDisclosureContent)
|
||||
.shouldDisplay(function() {
|
||||
@@ -174,7 +174,7 @@ export function uiSectionValidationIssues(id, severity, context) {
|
||||
linkEnter
|
||||
.append('span')
|
||||
.attr('class', 'autofix-all-link-text')
|
||||
.html(t.html('issues.fix_all.title'));
|
||||
.call(t.append('issues.fix_all.title'));
|
||||
|
||||
linkEnter
|
||||
.append('span')
|
||||
|
||||
@@ -46,7 +46,7 @@ export function uiSectionValidationRules(context) {
|
||||
.attr('class', 'issue-rules-link')
|
||||
.attr('role', 'button')
|
||||
.attr('href', '#')
|
||||
.html(t.html('issues.disable_all'))
|
||||
.call(t.append('issues.disable_all'))
|
||||
.on('click', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
context.validator().disableRules(_ruleKeys);
|
||||
@@ -57,7 +57,7 @@ export function uiSectionValidationRules(context) {
|
||||
.attr('class', 'issue-rules-link')
|
||||
.attr('role', 'button')
|
||||
.attr('href', '#')
|
||||
.html(t.html('issues.enable_all'))
|
||||
.call(t.append('issues.enable_all'))
|
||||
.on('click', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
context.validator().disableRules([]);
|
||||
@@ -106,7 +106,7 @@ export function uiSectionValidationRules(context) {
|
||||
.html(function(d) {
|
||||
var params = {};
|
||||
if (d === 'unsquare_way') {
|
||||
params.val = '<span class="square-degrees"></span>';
|
||||
params.val = { html: '<span class="square-degrees"></span>' };
|
||||
}
|
||||
return t.html('issues.' + d + '.title', params);
|
||||
});
|
||||
|
||||
@@ -78,7 +78,7 @@ export function uiSectionValidationStatus(context) {
|
||||
.merge(resetIgnoredEnter);
|
||||
|
||||
resetIgnored.select('a')
|
||||
.html(t('inspector.title_count', { title: t.html('issues.reset_ignored'), count: ignoredIssues.length }));
|
||||
.html(t.html('inspector.title_count', { title: { html: t.html('issues.reset_ignored') }, count: ignoredIssues.length }));
|
||||
|
||||
resetIgnored.on('click', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
@@ -96,7 +96,8 @@ export function uiSectionValidationStatus(context) {
|
||||
var hiddenIssues = context.validator().getIssues(hiddenOpts);
|
||||
if (hiddenIssues.length) {
|
||||
selection.select('.box .details')
|
||||
.html(t.html(
|
||||
.html('')
|
||||
.call(t.append(
|
||||
'issues.no_issues.hidden_issues.' + type,
|
||||
{ count: hiddenIssues.length.toString() }
|
||||
));
|
||||
@@ -104,7 +105,8 @@ export function uiSectionValidationStatus(context) {
|
||||
}
|
||||
}
|
||||
selection.select('.box .details')
|
||||
.html(t.html('issues.no_issues.hidden_issues.none'));
|
||||
.html('')
|
||||
.call(t.append('issues.no_issues.hidden_issues.none'));
|
||||
}
|
||||
|
||||
var messageType;
|
||||
@@ -159,7 +161,8 @@ export function uiSectionValidationStatus(context) {
|
||||
}
|
||||
|
||||
selection.select('.box .message')
|
||||
.html(t.html('issues.no_issues.message.' + messageType));
|
||||
.html('')
|
||||
.call(t.append('issues.no_issues.message.' + messageType));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export function uiSettingsCustomBackground() {
|
||||
|
||||
modal.select('.modal-section.header')
|
||||
.append('h3')
|
||||
.html(t.html('settings.custom_background.header'));
|
||||
.call(t.append('settings.custom_background.header'));
|
||||
|
||||
|
||||
var textSection = modal.select('.modal-section.message-text');
|
||||
@@ -70,7 +70,7 @@ export function uiSettingsCustomBackground() {
|
||||
buttonSection
|
||||
.insert('button', '.ok-button')
|
||||
.attr('class', 'button cancel-button secondary-action')
|
||||
.html(t.html('confirm.cancel'));
|
||||
.call(t.append('confirm.cancel'));
|
||||
|
||||
|
||||
buttonSection.select('.cancel-button')
|
||||
|
||||
@@ -30,7 +30,7 @@ export function uiSettingsCustomData(context) {
|
||||
|
||||
modal.select('.modal-section.header')
|
||||
.append('h3')
|
||||
.html(t.html('settings.custom_data.header'));
|
||||
.call(t.append('settings.custom_data.header'));
|
||||
|
||||
|
||||
var textSection = modal.select('.modal-section.message-text');
|
||||
@@ -38,7 +38,7 @@ export function uiSettingsCustomData(context) {
|
||||
textSection
|
||||
.append('pre')
|
||||
.attr('class', 'instructions-file')
|
||||
.html(t.html('settings.custom_data.file.instructions'));
|
||||
.call(t.append('settings.custom_data.file.instructions'));
|
||||
|
||||
textSection
|
||||
.append('input')
|
||||
@@ -58,12 +58,12 @@ export function uiSettingsCustomData(context) {
|
||||
|
||||
textSection
|
||||
.append('h4')
|
||||
.html(t.html('settings.custom_data.or'));
|
||||
.call(t.append('settings.custom_data.or'));
|
||||
|
||||
textSection
|
||||
.append('pre')
|
||||
.attr('class', 'instructions-url')
|
||||
.html(t.html('settings.custom_data.url.instructions'));
|
||||
.call(t.append('settings.custom_data.url.instructions'));
|
||||
|
||||
textSection
|
||||
.append('textarea')
|
||||
@@ -79,7 +79,7 @@ export function uiSettingsCustomData(context) {
|
||||
buttonSection
|
||||
.insert('button', '.ok-button')
|
||||
.attr('class', 'button cancel-button secondary-action')
|
||||
.html(t.html('confirm.cancel'));
|
||||
.call(t.append('confirm.cancel'));
|
||||
|
||||
|
||||
buttonSection.select('.cancel-button')
|
||||
|
||||
@@ -27,7 +27,7 @@ export function uiShortcuts(context) {
|
||||
.append('div')
|
||||
.attr('class', 'modal-section header')
|
||||
.append('h2')
|
||||
.html(t.html('shortcuts.title'));
|
||||
.call(t.append('shortcuts.title'));
|
||||
|
||||
fileFetcher.get('shortcuts')
|
||||
.then(function(data) {
|
||||
@@ -152,11 +152,11 @@ export function uiShortcuts(context) {
|
||||
selection
|
||||
.append('kbd')
|
||||
.attr('class', 'modifier')
|
||||
.html(function (d) { return uiCmd.display(d); });
|
||||
.text(function (d) { return uiCmd.display(d); });
|
||||
|
||||
selection
|
||||
.append('span')
|
||||
.html('+');
|
||||
.text('+');
|
||||
});
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ export function uiShortcuts(context) {
|
||||
selection
|
||||
.append('kbd')
|
||||
.attr('class', 'shortcut')
|
||||
.html(function (d) { return d.shortcut; });
|
||||
.text(function (d) { return d.shortcut; });
|
||||
}
|
||||
|
||||
if (i < nodes.length - 1) {
|
||||
@@ -211,7 +211,7 @@ export function uiShortcuts(context) {
|
||||
} else if (i === nodes.length - 1 && d.suffix) {
|
||||
selection
|
||||
.append('span')
|
||||
.html(d.suffix);
|
||||
.text(d.suffix);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -223,7 +223,7 @@ export function uiShortcuts(context) {
|
||||
|
||||
selection
|
||||
.append('span')
|
||||
.html('+');
|
||||
.text('+');
|
||||
|
||||
selection
|
||||
.append('span')
|
||||
|
||||
@@ -41,7 +41,7 @@ export function uiSourceSwitch(context) {
|
||||
selection
|
||||
.append('a')
|
||||
.attr('href', '#')
|
||||
.html(t.html('source_switch.live'))
|
||||
.call(t.append('source_switch.live'))
|
||||
.attr('class', 'live chip')
|
||||
.on('click', click);
|
||||
};
|
||||
|
||||
+12
-7
@@ -3,6 +3,7 @@ import { fileFetcher } from '../core/file_fetcher';
|
||||
import { t } from '../core/localizer';
|
||||
import { uiIntro } from './intro';
|
||||
import { uiModal } from './modal';
|
||||
import { uiSectionPrivacy } from './sections/privacy';
|
||||
|
||||
|
||||
export function uiSplash(context) {
|
||||
@@ -42,7 +43,7 @@ export function uiSplash(context) {
|
||||
.append('div')
|
||||
.attr('class','modal-section')
|
||||
.append('h3')
|
||||
.html(t.html('splash.welcome'));
|
||||
.call(t.append('splash.welcome'));
|
||||
|
||||
let modalSection = introModal
|
||||
.append('div')
|
||||
@@ -52,18 +53,22 @@ export function uiSplash(context) {
|
||||
.append('p')
|
||||
.html(t.html('splash.text', {
|
||||
version: context.version,
|
||||
website: '<a target="_blank" href="https://github.com/openstreetmap/iD/blob/develop/CHANGELOG.md#whats-new">changelog</a>',
|
||||
github: '<a target="_blank" href="https://github.com/openstreetmap/iD/issues">github.com</a>'
|
||||
website: { html: '<a target="_blank" href="https://github.com/openstreetmap/iD/blob/develop/CHANGELOG.md#whats-new">changelog</a>' },
|
||||
github: { html: '<a target="_blank" href="https://github.com/openstreetmap/iD/issues">github.com</a>' }
|
||||
}));
|
||||
|
||||
modalSection
|
||||
.append('p')
|
||||
.html(t.html('splash.privacy', {
|
||||
updateMessage: updateMessage,
|
||||
privacyLink: '<a target="_blank" href="https://github.com/openstreetmap/iD/blob/release/PRIVACY.md">' +
|
||||
t('splash.privacy_policy') + '</a>'
|
||||
privacyLink: { html: '<a target="_blank" href="https://github.com/openstreetmap/iD/blob/release/PRIVACY.md">' +
|
||||
t('splash.privacy_policy') + '</a>' }
|
||||
}));
|
||||
|
||||
uiSectionPrivacy(context)
|
||||
.label(t.html('splash.privacy_settings'))
|
||||
.render(modalSection);
|
||||
|
||||
let buttonWrap = introModal
|
||||
.append('div')
|
||||
.attr('class', 'modal-actions');
|
||||
@@ -84,7 +89,7 @@ export function uiSplash(context) {
|
||||
|
||||
walkthrough
|
||||
.append('div')
|
||||
.html(t.html('splash.walkthrough'));
|
||||
.call(t.append('splash.walkthrough'));
|
||||
|
||||
let startEditing = buttonWrap
|
||||
.append('button')
|
||||
@@ -99,7 +104,7 @@ export function uiSplash(context) {
|
||||
|
||||
startEditing
|
||||
.append('div')
|
||||
.html(t.html('splash.start'));
|
||||
.call(t.append('splash.start'));
|
||||
|
||||
modalSelection.select('button.close')
|
||||
.attr('class','hide');
|
||||
|
||||
@@ -22,14 +22,14 @@ export function uiStatus(context) {
|
||||
|
||||
} else if (apiStatus === 'rateLimited') {
|
||||
selection
|
||||
.html(t.html('osm_api_status.message.rateLimit'))
|
||||
.call(t.append('osm_api_status.message.rateLimit'))
|
||||
.append('a')
|
||||
.attr('href', '#')
|
||||
.attr('class', 'api-status-login')
|
||||
.attr('target', '_blank')
|
||||
.call(svgIcon('#iD-icon-out-link', 'inline'))
|
||||
.append('span')
|
||||
.html(t.html('login'))
|
||||
.call(t.append('login'))
|
||||
.on('click.login', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
osm.authenticate();
|
||||
@@ -47,11 +47,11 @@ export function uiStatus(context) {
|
||||
// eslint-disable-next-line no-warning-comments
|
||||
// TODO: nice messages for different error types
|
||||
selection
|
||||
.html(t.html('osm_api_status.message.error') + ' ')
|
||||
.call(t.append('osm_api_status.message.error', { suffix: ' ' }))
|
||||
.append('a')
|
||||
.attr('href', '#')
|
||||
// let the user manually retry their connection directly
|
||||
.html(t.html('osm_api_status.retry'))
|
||||
.call(t.append('osm_api_status.retry'))
|
||||
.on('click.retry', function(d3_event) {
|
||||
d3_event.preventDefault();
|
||||
throttledRetry();
|
||||
@@ -59,9 +59,9 @@ export function uiStatus(context) {
|
||||
}
|
||||
|
||||
} else if (apiStatus === 'readonly') {
|
||||
selection.html(t.html('osm_api_status.message.readonly'));
|
||||
selection.call(t.append('osm_api_status.message.readonly'));
|
||||
} else if (apiStatus === 'offline') {
|
||||
selection.html(t.html('osm_api_status.message.offline'));
|
||||
selection.call(t.append('osm_api_status.message.offline'));
|
||||
}
|
||||
|
||||
selection.attr('class', 'api-status ' + (err ? 'error' : apiStatus));
|
||||
@@ -70,7 +70,7 @@ export function uiStatus(context) {
|
||||
osm.on('apiStatusChange.uiStatus', update);
|
||||
|
||||
context.history().on('storage_error', () => {
|
||||
selection.html(t.html('osm_api_status.message.local_storage_full'));
|
||||
selection.call(t.append('osm_api_status.message.local_storage_full'));
|
||||
selection.attr('class', 'api-status error');
|
||||
});
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user