From d0d94dd19a40a97bb7b2037ecc9e17b71d8aa949 Mon Sep 17 00:00:00 2001 From: Kyle Hensel Date: Sat, 25 May 2024 16:07:12 +1000 Subject: [PATCH] iD#10254 support 3rd-party icons for preset fields --- modules/svg/icon.js | 13 +++++++++++++ modules/ui/fields/combo.js | 25 ++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/modules/svg/icon.js b/modules/svg/icon.js index b819221f9ce..05936a509cf 100644 --- a/modules/svg/icon.js +++ b/modules/svg/icon.js @@ -10,3 +10,16 @@ export function svgIcon(name, svgklass, useklass) { .attr('class', useklass); }; } + +/** @param {string} url */ +export function svgIconExternal(url) { + /** @param {import("d3-selection").Selection} selection */ + return function drawIcon(selection) { + selection.selectAll('img.icon') + .data([0]) + .enter() + .append('img') + .attr('class', 'icon') + .attr('src', url); + }; +} diff --git a/modules/ui/fields/combo.js b/modules/ui/fields/combo.js index 7ddb84cb536..90ab4f96bab 100644 --- a/modules/ui/fields/combo.js +++ b/modules/ui/fields/combo.js @@ -4,11 +4,12 @@ import { drag as d3_drag } from 'd3-drag'; import * as countryCoder from '@rapideditor/country-coder'; import { fileFetcher } from '../../core/file_fetcher'; +import { prefs } from '../../core/preferences'; import { osmEntity } from '../../osm/entity'; import { t } from '../../core/localizer'; import { services } from '../../services'; import { uiCombobox } from '../combobox'; -import { svgIcon } from '../../svg/icon'; +import { svgIcon, svgIconExternal } from '../../svg/icon'; import { utilKeybinding } from '../../util/keybinding'; import { utilArrayUniq, utilGetSetValue, utilNoAuto, utilRebind, utilTotalExtent, utilUnicodeCharsCount } from '../../util'; @@ -22,6 +23,8 @@ export { uiFieldCombo as uiFieldTypeCombo }; +const showThirdPartyIcons = prefs('preferences.privacy.thirdpartyicons') || 'true'; + export function uiFieldCombo(field, context) { var dispatch = d3_dispatch('change'); var _isMulti = (field.type === 'multiCombo' || field.type === 'manyCombo'); @@ -305,7 +308,15 @@ export function uiFieldCombo(field, context) { .insert('span', ':first-child') .attr('class', 'tag-value-icon'); if (iconsField.icons[value]) { - span.call(svgIcon(`#${iconsField.icons[value]}`)); + const isExternal = ( + iconsField.icons[value].startsWith('https://') && + showThirdPartyIcons === 'true' + ); + span.call( + isExternal + ? svgIconExternal(iconsField.icons[value]) + : svgIcon(`#${iconsField.icons[value]}`) + ); } disp.call(this, selection); }; @@ -613,12 +624,20 @@ export function uiFieldCombo(field, context) { if (iconsField.icons) { container.selectAll('.tag-value-icon').remove(); if (iconsField.icons[value]) { + const isExternal = ( + iconsField.icons[value].startsWith('https://') && + showThirdPartyIcons === 'true' + ); container.selectAll('.tag-value-icon') .data([value]) .enter() .insert('div', 'input') .attr('class', 'tag-value-icon') - .call(svgIcon(`#${iconsField.icons[value]}`)); + .call( + isExternal + ? svgIconExternal(iconsField.icons[value]) + : svgIcon(`#${iconsField.icons[value]}`) + ); } } }