Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion css/30_highways.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
preset-icon-container/* highways */
/* preset-icon-container highways */

/* defaults */
.preset-icon .icon.tag-highway.other-line {
color: #fff;
fill: #777;
}

path.line.casing.tag-highway {
stroke: #444;
}

path.line.stroke.tag-highway {
stroke: #ccc;
}
Expand Down
67 changes: 58 additions & 9 deletions modules/ui/fields/textarea.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ import {
utilRebind
} from '../../util';
import { uiLengthIndicator } from '..';

import { svgIcon } from '../../svg/icon'; // ← ADDED
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the point of // ← ADDED comments?

these should be removed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(if this PR makes sense)


export function uiFieldTextarea(field, context) {
var dispatch = d3_dispatch('change');
var input = d3_select(null);
var wrap = d3_select(null); // ← ADDED
var _lengthIndicator = uiLengthIndicator(context.maxCharsForTagValue())
.silent(field.usage === 'changeset' && field.key === 'comment');
var _tags;


function textarea(selection) {
var wrap = selection.selectAll('.form-field-input-wrap')
wrap = selection.selectAll('.form-field-input-wrap')
.data([0]);

wrap = wrap.enter()
Expand All @@ -36,15 +36,24 @@ export function uiFieldTextarea(field, context) {
.attr('dir', 'auto')
.attr('id', field.domId)
.call(utilNoAuto)
.on('input', change(true))
.on('blur', change())
.on('change', change())
.on('input', function () {
change(true)();
updatePatternValidation(); // ← ADDED
})
.on('blur', function () {
change()();
updatePatternValidation(); // ← ADDED
})
.on('change', function () {
change()();
updatePatternValidation(); // ← ADDED
})
.merge(input);

wrap.call(_lengthIndicator);

function change(onInput) {
return function() {
return function () {

var val = utilGetSetValue(input);
if (!onInput) val = context.cleanTagValue(val);
Expand All @@ -58,9 +67,47 @@ export function uiFieldTextarea(field, context) {
};
}
}

function updatePatternValidation() {
if (!field.pattern || !wrap || wrap.empty()) return;

const value = utilGetSetValue(input).trim();

if (!value) {
wrap.selectAll('.form-field-pattern-info').remove();
return;
}

let isInvalid = false;
try {
const regex = new RegExp(field.pattern);
isInvalid = !regex.test(value);
} catch {
return;
}

const info = wrap.selectAll('.form-field-pattern-info')
.data(isInvalid ? [0] : []);

textarea.tags = function(tags) {
const enter = info.enter()
.append('div')
.attr('class', 'form-field-pattern-info');

enter
.append('span')
.call(svgIcon('#iD-icon-info'));

enter
.append('span')
.attr('class', 'form-field-pattern-info-text')
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The translation key 'inspector.invalid_format' is referenced but there's no indication in the PR that this translation string exists. Consider documenting where this key should be defined or adding a comment explaining the expected translation setup.

Suggested change
.attr('class', 'form-field-pattern-info-text')
.attr('class', 'form-field-pattern-info-text')
// `inspector.invalid_format` is defined in the shared inspector translations

Copilot uses AI. Check for mistakes.
.text(t('inspector.invalid_format'));

info.exit().remove();
}
// ============================


textarea.tags = function (tags) {
_tags = tags;

var isMixed = Array.isArray(tags[field.key]);
Expand All @@ -73,10 +120,12 @@ export function uiFieldTextarea(field, context) {
if (!isMixed) {
_lengthIndicator.update(tags[field.key]);
}

updatePatternValidation();
};


textarea.focus = function() {
textarea.focus = function () {
input.node().focus();
};

Expand Down
2 changes: 1 addition & 1 deletion modules/validations/crossing_ways.js
Original file line number Diff line number Diff line change
Expand Up @@ -841,4 +841,4 @@ export function validationCrossingWays(context) {
validation.type = type;

return validation;
}
}