diff --git a/CHANGES.md b/CHANGES.md index 92f55843f3..1383d34c64 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ - Updated translations - #3123: Contacts do not show up online until chat is opened with them. - #3156: Add function to prevent drag stutter effect over iframes when resize is called in overlay mode +- #3161: Re-add ability to convert OpenStreetMap URLs into `geo:` URIs in sent messages and fix issue #1850 - #3165: Use configured nickname in profile view in the control box - New config option [stanza_timeout](https://conversejs.org/docs/html/configuration.html#stanza-timeout) diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst index 1f4b6047d2..0c6dc72cdb 100644 --- a/docs/source/configuration.rst +++ b/docs/source/configuration.rst @@ -928,17 +928,17 @@ Accepts a string or array of strings. Any query strings from URLs that match thi geouri_regex ------------ -* Default: ``/https:\/\/www.openstreetmap.org\/.*#map=[0-9]+\/([\-0-9.]+)\/([\-0-9.]+)\S*/g`` +* Default: ``/https:\/\/www\.openstreetmap\.org\/\#map=(?[0-9]+)\/(?[\-0-9.]+)\/(?[\-0-9.]+)/g`` Regular expression used to extract geo coordinates from links to openstreetmap. geouri_replacement ------------------ -* Default: ``'https://www.openstreetmap.org/?mlat=$1&mlon=$2#map=18/$1/$2'`` +* Default: ``https://www.openstreetmap.org/?mlat=$&mlon=$#map=$/$/$`` -String used to replace geo-URIs with. Ought to be a link to osm or similar. ``$1`` and ``$2`` is replaced by -latitude and longitude respectively. +String used to replace geo-URIs with. Ought to be a link to osm or similar. ``$``, ``$``, and ``$`` is replaced by +latitude, longitude, and zoom level respectively. hide_muc_participants --------------------- diff --git a/src/headless/plugins/chat/model.js b/src/headless/plugins/chat/model.js index 78f22da801..4e59a6c655 100644 --- a/src/headless/plugins/chat/model.js +++ b/src/headless/plugins/chat/model.js @@ -840,7 +840,7 @@ const ChatBox = ModelWithContact.extend({ const is_spoiler = !!this.get('composing_spoiler'); const origin_id = u.getUniqueId(); const text = attrs?.body; - const body = text ? u.shortnamesToUnicode(text) : undefined; + const body = text ? u.httpToGeoUri(u.shortnamesToUnicode(text), _converse) : undefined; attrs = Object.assign({}, attrs, { 'from': _converse.bare_jid, 'fullname': _converse.xmppstatus.get('fullname'), diff --git a/src/headless/plugins/muc/muc.js b/src/headless/plugins/muc/muc.js index 8d41025d70..b4bfc0500f 100644 --- a/src/headless/plugins/muc/muc.js +++ b/src/headless/plugins/muc/muc.js @@ -1007,7 +1007,7 @@ const ChatRoomMixin = { [text, references] = this.parseTextForReferences(attrs.body); } const origin_id = getUniqueId(); - const body = text ? u.shortnamesToUnicode(text) : undefined; + const body = text ? u.httpToGeoUri(u.shortnamesToUnicode(text), _converse) : undefined; attrs = Object.assign({}, attrs, { body, is_spoiler, diff --git a/src/headless/shared/settings/constants.js b/src/headless/shared/settings/constants.js index e8738888f2..d519a683d5 100644 --- a/src/headless/shared/settings/constants.js +++ b/src/headless/shared/settings/constants.js @@ -45,8 +45,8 @@ export const DEFAULT_SETTINGS = { connection_options: {}, credentials_url: null, // URL from where login credentials can be fetched discover_connection_methods: true, - geouri_regex: /https\:\/\/www.openstreetmap.org\/.*#map=[0-9]+\/([\-0-9.]+)\/([\-0-9.]+)\S*/g, - geouri_replacement: 'https://www.openstreetmap.org/?mlat=$1&mlon=$2#map=18/$1/$2', + geouri_regex: /https:\/\/www\.openstreetmap\.org\/\#map=(?[0-9]+)\/(?[\-0-9.]+)\/(?[\-0-9.]+)/g, + geouri_replacement: 'https://www.openstreetmap.org/?mlat=$&mlon=$#map=$/$/$', i18n: undefined, jid: undefined, keepalive: true, diff --git a/src/headless/utils/core.js b/src/headless/utils/core.js index b9acf8d288..ab5f997027 100644 --- a/src/headless/utils/core.js +++ b/src/headless/utils/core.js @@ -485,6 +485,11 @@ export function getUniqueId (suffix) { } } +u.httpToGeoUri = function(text) { + const replacement = 'geo:$,$;z=$'; + const geouri_regex = settings_api.get("geouri_regex"); + return geouri_regex ? text.replace(geouri_regex, replacement) : text; +}; /** * Clears the specified timeout and interval. diff --git a/src/plugins/chatview/tests/messages.js b/src/plugins/chatview/tests/messages.js index 777494c184..43465b3551 100644 --- a/src/plugins/chatview/tests/messages.js +++ b/src/plugins/chatview/tests/messages.js @@ -262,7 +262,25 @@ describe("A Chat Message", function () { expect(_converse.api.chatboxes.get).not.toHaveBeenCalled(); })); - it("will render Openstreetmap-URL from geo-URI", + it("will render Openstreetmap-URL from geo-URI with zoom level", + mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { + + await mock.waitForRoster(_converse, 'current', 1); + const message = "geo:37.786971,-122.399677;z=7"; + const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; + await mock.openChatBoxFor(_converse, contact_jid); + const view = _converse.chatboxviews.get(contact_jid); + spyOn(view.model, 'sendMessage').and.callThrough(); + await mock.sendMessage(view, message); + await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-msg').length, 1000); + expect(view.model.sendMessage).toHaveBeenCalled(); + const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop(); + await u.waitUntil(() => msg.innerHTML.replace(/\/g, '') === + 'https://www.openstreetmap.org/?mlat=37.786971&mlon=-122.399677#map=7/37.786971/-122.399677'); + })); + + it("will render Openstreetmap-URL from geo-URI without zoom level", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { await mock.waitForRoster(_converse, 'current', 1); @@ -277,7 +295,41 @@ describe("A Chat Message", function () { const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop(); await u.waitUntil(() => msg.innerHTML.replace(/\/g, '') === 'https://www.openstreetmap.org/?mlat=37.786971&mlon=-122.399677#map=18/37.786971/-122.399677'); + 'mlon=-122.399677#map=/37.786971/-122.399677">https://www.openstreetmap.org/?mlat=37.786971&mlon=-122.399677#map=/37.786971/-122.399677'); + })); + + it("will not render geo-URI from Openstreetmap-URL", + mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { + + await mock.waitForRoster(_converse, 'current', 1); + const message = "https://www.openstreetmap.org/#map=7/51.724/6.630"; + const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; + await mock.openChatBoxFor(_converse, contact_jid); + const view = _converse.chatboxviews.get(contact_jid); + spyOn(view.model, 'sendMessage').and.callThrough(); + await mock.sendMessage(view, message); + await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-msg').length, 1000); + expect(view.model.sendMessage).toHaveBeenCalled(); + const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop(); + await u.waitUntil(() => msg.innerHTML.replace(/\/g, '') === + 'geo:51.724,6.630;z=7'); + })); + + it("will not render geo-URI from Openstreetmap-URL if additional information present in URL", + mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { + + await mock.waitForRoster(_converse, 'current', 1); + const message = "https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&route=51.507%2C-0.128%3B52.517%2C13.389#map=7/51.724/6.630"; + const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; + await mock.openChatBoxFor(_converse, contact_jid); + const view = _converse.chatboxviews.get(contact_jid); + spyOn(view.model, 'sendMessage').and.callThrough(); + await mock.sendMessage(view, message); + await u.waitUntil(() => view.querySelectorAll('.chat-content .chat-msg').length, 1000); + expect(view.model.sendMessage).toHaveBeenCalled(); + const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view).pop(); + await u.waitUntil(() => msg.innerHTML.replace(/\/g, '') === + 'https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&route=51.507%2C-0.128%3B52.517%2C13.389#map=7/51.724/6.630'); })); it("can be a carbon message, as defined in XEP-0280", diff --git a/src/shared/rich-text.js b/src/shared/rich-text.js index 019aa9bec4..a50aec3533 100644 --- a/src/shared/rich-text.js +++ b/src/shared/rich-text.js @@ -159,7 +159,7 @@ export class RichText extends String { * the start of the message body text. */ addMapURLs (text, offset) { - const regex = /geo:([\-0-9.]+),([\-0-9.]+)(?:,([\-0-9.]+))?(?:\?(.*))?/g; + const regex = /geo:(?[\-0-9.]+),(?[\-0-9.]+)(?:,(?:[\-0-9.]+))?(?:;\w+(?\d+))?(?:;\w+=\w+)*/g; const matches = text.matchAll(regex); for (const m of matches) { this.addTemplateResult(