diff --git a/css/80_app.css b/css/80_app.css index 3c08bd04b..4d5984c02 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -5201,13 +5201,16 @@ a.user-info { display: none; } -.field-warning, .changeset-info, .request-review, .commit-info { margin-bottom: 10px; } +.field-warning { + margin-top: 10px; +} + .request-review label { cursor: pointer; } diff --git a/data/core.yaml b/data/core.yaml index 72c4a8427..a67b88248 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -615,7 +615,7 @@ en: comment_needed_message: Please add a changeset comment first. about_changeset_comments: About changeset comments about_changeset_comments_link: //wiki.openstreetmap.org/wiki/Good_changeset_comments - changeset_comment_length_warning: "Changeset comments can have a maximum of 255 characters" + changeset_comment_length_warning: "Changeset comments can have a maximum of {maxChars} characters" google_warning: "You mentioned Google in this comment: remember that copying from Google Maps is strictly forbidden." google_warning_link: https://www.openstreetmap.org/copyright contributors: diff --git a/modules/ui/changeset_editor.js b/modules/ui/changeset_editor.js index 1ff6580b2..d929a72d9 100644 --- a/modules/ui/changeset_editor.js +++ b/modules/ui/changeset_editor.js @@ -1,4 +1,5 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; +import { select as d3_select } from 'd3-selection'; import { presetManager } from '../presets'; import { t } from '../core/localizer'; @@ -6,7 +7,7 @@ import { svgIcon } from '../svg/icon'; import { uiCombobox} from './combobox'; import { uiField } from './field'; import { uiFormFields } from './form_fields'; -import { utilArrayUniqBy, utilRebind, utilTriggerEvent } from '../util'; +import { utilArrayUniqBy, utilCleanOsmString, utilRebind, utilTriggerEvent, utilUnicodeCharsCount } from '../util'; export function uiChangesetEditor(context) { @@ -85,10 +86,26 @@ export function uiChangesetEditor(context) { } } - var hasGoogle = _tags.comment.match(/google/i); - var commentTooLong = _tags.comment.length > 255; + // Show warning(s) if comment mentions Google or comment length exceeds 255 chars + const warnings = []; + if (_tags.comment.match(/google/i)) { + warnings.push({ + id: 'contains "google"', + msg: t.append('commit.google_warning'), + link: t('commit.google_warning_link') + }); + } + const maxChars = context.maxCharsForTagValue(); + const strLen = utilUnicodeCharsCount(utilCleanOsmString(_tags.comment, Number.POSITIVE_INFINITY)); + if (strLen > maxChars || !true) { + warnings.push({ + id: 'message too long', + msg: t.append('commit.changeset_comment_length_warning', { maxChars: maxChars }), + }); + } + var commentWarning = selection.select('.form-field-comment').selectAll('.comment-warning') - .data(hasGoogle || commentTooLong ? [0] : []); + .data(warnings, d => d.id); commentWarning.exit() .transition() @@ -96,30 +113,31 @@ export function uiChangesetEditor(context) { .style('opacity', 0) .remove(); - function displayWarningMessage(msg, link) { - var commentEnter = commentWarning.enter() - .insert('div', '.tag-reference-body') - .attr('class', 'field-warning comment-warning') - .style('opacity', 0); + var commentEnter = commentWarning.enter() + .insert('div', '.comment-warning') + .attr('class', 'comment-warning field-warning') + .style('opacity', 0); - commentEnter - .append('a') - .attr('target', '_blank') - .call(svgIcon('#iD-icon-alert', 'inline')) - .attr('href', t(link)) - .append('span') - .call(t.append(msg)); + commentEnter + .call(svgIcon('#iD-icon-alert', 'inline')) + .append('span'); - commentEnter - .transition() - .duration(200) - .style('opacity', 1); - } + commentEnter + .transition() + .duration(200) + .style('opacity', 1); - // Add warning if comment mentions Google or comment length - // exceeds 255 chars - if (hasGoogle) displayWarningMessage('commit.google_warning', 'commit.google_warning_link'); - if (commentTooLong) displayWarningMessage('commit.changeset_comment_length_warning', 'commit.about_changeset_comments_link'); + commentWarning.merge(commentEnter).selectAll('div > span') + .text('') + .each(function(d) { + let selection = d3_select(this); + if (d.link) { + selection = selection.append('a') + .attr('target', '_blank') + .attr('href', d.link); + } + selection.call(d.msg); + }); } diff --git a/modules/ui/fields/textarea.js b/modules/ui/fields/textarea.js index 59fe8b6a2..fb56f7be1 100644 --- a/modules/ui/fields/textarea.js +++ b/modules/ui/fields/textarea.js @@ -13,7 +13,8 @@ import { uiLengthIndicator } from '..'; export function uiFieldTextarea(field, context) { var dispatch = d3_dispatch('change'); var input = d3_select(null); - var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue()); + var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue()) + .silent(field.usage === 'changeset' && field.key === 'comment'); var _tags; diff --git a/modules/ui/length_indicator.js b/modules/ui/length_indicator.js index a7e84857d..d6e034f88 100644 --- a/modules/ui/length_indicator.js +++ b/modules/ui/length_indicator.js @@ -17,6 +17,7 @@ export function uiLengthIndicator(maxChars) { selection.text(''); t.append('inspector.max_length_reached', { maxChars })(selection); }); + var _silent = false; var lengthIndicator = function(selection) { _wrap = selection.selectAll('span.length-indicator-wrap').data([0]); @@ -47,6 +48,7 @@ export function uiLengthIndicator(maxChars) { : 0) .style('pointer-events', d => d > maxChars * 0.8 ? null: 'none'); + if (_silent) return; if (strLen > maxChars) { _tooltip.show(); } else { @@ -54,5 +56,11 @@ export function uiLengthIndicator(maxChars) { } }; + lengthIndicator.silent = function(val) { + if (!arguments.length) return _silent; + _silent = val; + return lengthIndicator; + }; + return lengthIndicator; }