diff --git a/core/code/portal_data.js b/core/code/portal_data.js
index 334cb356d..f04ee24ab 100644
--- a/core/code/portal_data.js
+++ b/core/code/portal_data.js
@@ -1,3 +1,5 @@
+/* global L -- eslint */
+
/**
* @file Contain misc functions to get portal info
* @module portal_data
@@ -73,6 +75,50 @@ window.getPortalFieldsCount = function (guid) {
return fields.length;
};
+/**
+ * Zooms the map to a specific portal and shows its details if available.
+ *
+ * @function zoomToAndShowPortal
+ * @param {string} guid - The globally unique identifier of the portal.
+ * @param {L.LatLng|number[]} latlng - The latitude and longitude of the portal.
+ */
+window.zoomToAndShowPortal = function (guid, latlng) {
+ window.map.setView(latlng, window.DEFAULT_ZOOM);
+ // if the data is available, render it immediately. Otherwise defer
+ // until it becomes available.
+ if (window.portals[guid]) window.renderPortalDetails(guid);
+ else window.urlPortal = guid;
+};
+
+/**
+ * Selects a portal by its latitude and longitude.
+ *
+ * @function selectPortalByLatLng
+ * @param {number|Array|L.LatLng} lat - The latitude of the portal
+ * or an array or L.LatLng object containing both latitude and longitude.
+ * @param {number} [lng] - The longitude of the portal.
+ */
+window.selectPortalByLatLng = function (lat, lng) {
+ if (lng === undefined && lat instanceof Array) {
+ lng = lat[1];
+ lat = lat[0];
+ } else if (lng === undefined && lat instanceof L.LatLng) {
+ lng = lat.lng;
+ lat = lat.lat;
+ }
+ for (var guid in window.portals) {
+ var latlng = window.portals[guid].getLatLng();
+ if (latlng.lat === lat && latlng.lng === lng) {
+ window.renderPortalDetails(guid);
+ return;
+ }
+ }
+
+ // not currently visible
+ window.urlPortalLL = [lat, lng];
+ window.map.setView(window.urlPortalLL, window.DEFAULT_ZOOM);
+};
+
(function () {
var cache = {};
var cache_level = 0;
diff --git a/core/code/portal_detail_display.js b/core/code/portal_detail_display.js
index e6235e528..d58662943 100644
--- a/core/code/portal_detail_display.js
+++ b/core/code/portal_detail_display.js
@@ -362,3 +362,62 @@ window.selectPortal = function (guid) {
window.runHooks('portalSelected', { selectedPortalGuid: guid, unselectedPortalGuid: oldPortalGuid });
return update;
};
+
+/**
+ * Changes the coordinates and map scale to show the range for portal links.
+ *
+ * @function rangeLinkClick
+ */
+window.rangeLinkClick = function () {
+ if (window.portalRangeIndicator) window.map.fitBounds(window.portalRangeIndicator.getBounds());
+ if (window.isSmartphone()) window.show('map');
+};
+
+/**
+ * Creates a link to open a specific portal in Ingress Prime.
+ *
+ * @function makePrimeLink
+ * @param {string} guid - The globally unique identifier of the portal.
+ * @param {number} lat - The latitude of the portal.
+ * @param {number} lng - The longitude of the portal.
+ * @returns {string} The Ingress Prime link for the portal
+ */
+window.makePrimeLink = function (guid, lat, lng) {
+ return `https://link.ingress.com/?link=https%3A%2F%2Fintel.ingress.com%2Fportal%2F${guid}&apn=com.nianticproject.ingress&isi=576505181&ibi=com.google.ingress&ifl=https%3A%2F%2Fapps.apple.com%2Fapp%2Fingress%2Fid576505181&ofl=https%3A%2F%2Fintel.ingress.com%2Fintel%3Fpll%3D${lat}%2C${lng}`;
+};
+
+/**
+ * Generates a permalink URL based on the specified latitude and longitude and additional options.
+ *
+ * @param {L.LatLng|number[]} [latlng] - The latitude and longitude for the permalink.
+ * Can be omitted to create mapview-only permalink.
+ * @param {Object} [options] - Additional options for permalink generation.
+ * @param {boolean} [options.includeMapView] - Include current map view in the permalink.
+ * @param {boolean} [options.fullURL] - Generate a fully qualified URL (default: relative link).
+ * @returns {string} The generated permalink URL.
+ */
+window.makePermalink = function (latlng, options) {
+ options = options || {};
+
+ function round(l) {
+ // ensures that lat,lng are with same precision as in stock intel permalinks
+ return Math.floor(l * 1e6) / 1e6;
+ }
+ var args = [];
+ if (!latlng || options.includeMapView) {
+ var c = window.map.getCenter();
+ args.push('ll=' + [round(c.lat), round(c.lng)].join(','), 'z=' + window.map.getZoom());
+ }
+ if (latlng) {
+ if ('lat' in latlng) {
+ latlng = [latlng.lat, latlng.lng];
+ }
+ args.push('pll=' + latlng.join(','));
+ }
+ var url = '';
+ if (options.fullURL) {
+ url += new URL(document.baseURI).origin;
+ }
+ url += '/';
+ return url + '?' + args.join('&');
+};
diff --git a/core/code/portal_detail_display_tools.js b/core/code/portal_detail_display_tools.js
index d02a9f190..6b5419184 100644
--- a/core/code/portal_detail_display_tools.js
+++ b/core/code/portal_detail_display_tools.js
@@ -311,3 +311,27 @@ window.getMitigationText = function (d, linkCount) {
return ['shielding', mitigationShort, title];
};
+
+/**
+ * Displays a dialog with links to show the specified location on various map services.
+ *
+ * @function showPortalPosLinks
+ * @param {number} lat - Latitude of the location.
+ * @param {number} lng - Longitude of the location.
+ * @param {string} name - Name of the location.
+ */
+window.showPortalPosLinks = function (lat, lng, name) {
+ var encoded_name = encodeURIComponent(name);
+ var qrcode = '
';
+ var script = "";
+ var gmaps = 'Google Maps';
+ var bingmaps =
+ 'Bing Maps';
+ var osm = 'OpenStreetMap';
+ var latLng = '' + lat + ',' + lng + '';
+ window.dialog({
+ html: '' + qrcode + script + gmaps + '; ' + bingmaps + '; ' + osm + '
' + latLng + '
',
+ title: name,
+ id: 'poslinks',
+ });
+};
diff --git a/core/code/utils.js b/core/code/utils.js
index 059adcda8..790b6debe 100644
--- a/core/code/utils.js
+++ b/core/code/utils.js
@@ -224,54 +224,6 @@ const formatDistance = (distance) => {
return `${IITC.utils.formatNumber(value)}${unit}`;
};
-/**
- * Changes the coordinates and map scale to show the range for portal links.
- *
- * @memberof IITC.utils
- * @function rangeLinkClick
- */
-const rangeLinkClick = function () {
- if (window.portalRangeIndicator) window.map.fitBounds(window.portalRangeIndicator.getBounds());
- if (window.isSmartphone()) window.show('map');
-};
-
-/**
- * Displays a dialog with links to show the specified location on various map services.
- *
- * @memberof IITC.utils
- * @function showPortalPosLinks
- * @param {number} lat - Latitude of the location.
- * @param {number} lng - Longitude of the location.
- * @param {string} name - Name of the location.
- */
-const showPortalPosLinks = (lat, lng, name) => {
- const encodedName = encodeURIComponent(name);
-
- const qrcodeContainer = ``;
- const qrcodeScript = ``;
-
- const gmapsLink = `Google Maps`;
- const bingmapsLink = `Bing Maps`;
- const osmLink = `OpenStreetMap`;
-
- const latLngDisplay = `${lat}, ${lng}`;
-
- const content = `
-
- ${qrcodeContainer}
- ${qrcodeScript}
- ${gmapsLink}; ${bingmapsLink}; ${osmLink}
- ${latLngDisplay}
-
- `;
-
- window.dialog({
- html: content,
- title: name,
- id: 'poslinks',
- });
-};
-
/**
* Checks if the device is a touch-enabled device.
* Alias for `L.Browser.touch()`
@@ -296,52 +248,6 @@ const scrollBottom = (elm) => {
return element.scrollHeight - element.clientHeight - element.scrollTop;
};
-/**
- * Zooms the map to a specific portal and shows its details if available.
- *
- * @memberof IITC.utils
- * @function zoomToAndShowPortal
- * @param {string} guid - The globally unique identifier of the portal.
- * @param {L.LatLng|number[]} latlng - The latitude and longitude of the portal.
- */
-const zoomToAndShowPortal = function (guid, latlng) {
- window.map.setView(latlng, window.DEFAULT_ZOOM);
- // if the data is available, render it immediately. Otherwise defer
- // until it becomes available.
- if (window.portals[guid]) window.renderPortalDetails(guid);
- else window.urlPortal = guid;
-};
-
-/**
- * Selects a portal by its latitude and longitude.
- *
- * @memberof IITC.utils
- * @function selectPortalByLatLng
- * @param {number|Array|L.LatLng} lat - The latitude of the portal
- * or an array or L.LatLng object containing both latitude and longitude.
- * @param {number} [lng] - The longitude of the portal.
- */
-const selectPortalByLatLng = function (lat, lng) {
- if (lng === undefined && lat instanceof Array) {
- lng = lat[1];
- lat = lat[0];
- } else if (lng === undefined && lat instanceof L.LatLng) {
- lng = lat.lng;
- lat = lat.lat;
- }
- for (var guid in window.portals) {
- var latlng = window.portals[guid].getLatLng();
- if (latlng.lat === lat && latlng.lng === lng) {
- window.renderPortalDetails(guid);
- return;
- }
- }
-
- // not currently visible
- window.urlPortalLL = [lat, lng];
- window.map.setView(window.urlPortalLL, window.DEFAULT_ZOOM);
-};
-
/**
* Escapes special characters in a string for use in JavaScript.
* (for strings passed as parameters to html onclick="..." for example)
@@ -532,52 +438,6 @@ const isPointInPolygon = (polygon, point) => {
return !!inside;
};
-/**
- * Creates a link to open a specific portal in Ingress Prime.
- *
- * @memberof IITC.utils
- * @function makePrimeLink
- * @param {string} guid - The globally unique identifier of the portal.
- * @param {number} lat - The latitude of the portal.
- * @param {number} lng - The longitude of the portal.
- * @returns {string} The Ingress Prime link for the portal
- */
-const makePrimeLink = function (guid, lat, lng) {
- return `https://link.ingress.com/?link=https%3A%2F%2Fintel.ingress.com%2Fportal%2F${guid}&apn=com.nianticproject.ingress&isi=576505181&ibi=com.google.ingress&ifl=https%3A%2F%2Fapps.apple.com%2Fapp%2Fingress%2Fid576505181&ofl=https%3A%2F%2Fintel.ingress.com%2Fintel%3Fpll%3D${lat}%2C${lng}`;
-};
-
-/**
- * Generates a permalink URL based on the specified latitude and longitude and additional options.
- *
- * @memberof IITC.utils
- * @param {L.LatLng|number[]} [latlng] - The latitude and longitude for the permalink.
- * Can be omitted to create mapview-only permalink.
- * @param {Object} [options={}] - Additional options for permalink generation.
- * @param {boolean} [options.includeMapView=false] - Include current map view in the permalink.
- * @param {boolean} [options.fullURL=false] - Generate a fully qualified URL (default: relative link).
- * @returns {string} The generated permalink URL.
- */
-const makePermalink = (latlng, options = {}) => {
- const { includeMapView = false, fullURL = false } = options;
-
- // Rounds latitude/longitude to match stock intel permalinks precision
- const round = (l) => Math.floor(l * 1e6) / 1e6;
-
- const params = [];
- if (!latlng || includeMapView) {
- const center = window.map.getCenter();
- params.push(`ll=${round(center.lat)},${round(center.lng)}`);
- params.push(`z=${window.map.getZoom()}`);
- }
- if (latlng) {
- const [lat, lng] = 'lat' in latlng ? [latlng.lat, latlng.lng] : latlng;
- params.push(`pll=${lat},${lng}`);
- }
- const baseURL = fullURL ? new URL(document.baseURI).origin : '';
-
- return `${baseURL}/?${params.join('&')}`;
-};
-
IITC.utils = {
getURLParam,
getCookie,
@@ -590,12 +450,8 @@ IITC.utils = {
unixTimeToHHmm,
formatInterval,
formatDistance,
- rangeLinkClick,
- showPortalPosLinks,
isTouchDevice,
scrollBottom,
- zoomToAndShowPortal,
- selectPortalByLatLng,
escapeJavascriptString,
escapeHtmlSpecialChars,
prettyEnergy,
@@ -606,8 +462,6 @@ IITC.utils = {
clampLatLng,
clampLatLngBounds,
isPointInPolygon,
- makePrimeLink,
- makePermalink,
};
// Map of legacy function names to their new names (or the same name if not renamed)
@@ -623,12 +477,8 @@ const legacyFunctionMappings = {
unixTimeToHHmm: 'unixTimeToHHmm',
formatInterval: 'formatInterval',
formatDistance: 'formatDistance',
- rangeLinkClick: 'rangeLinkClick',
- showPortalPosLinks: 'showPortalPosLinks',
isTouchDevice: 'isTouchDevice',
scrollBottom: 'scrollBottom',
- zoomToAndShowPortal: 'zoomToAndShowPortal',
- selectPortalByLatLng: 'selectPortalByLatLng',
escapeJavascriptString: 'escapeJavascriptString',
escapeHtmlSpecialChars: 'escapeHtmlSpecialChars',
prettyEnergy: 'prettyEnergy',
@@ -639,8 +489,6 @@ const legacyFunctionMappings = {
clampLatLng: 'clampLatLng',
clampLatLngBounds: 'clampLatLngBounds',
pnpoly: 'isPointInPolygon',
- makePrimeLink: 'makePrimeLink',
- makePermalink: 'makePermalink',
};
// Set up synchronization between `window` and `IITC.utils` with new names
diff --git a/test/utils.spec.js b/test/utils.spec.js
index 8cb9df749..93a8461d8 100644
--- a/test/utils.spec.js
+++ b/test/utils.spec.js
@@ -449,60 +449,3 @@ describe('IITC.utils.clamp', () => {
expect(result).to.equal(-5);
});
});
-describe('IITC.utils.makePermalink', () => {
- beforeEach(() => {
- // Mock window.map object
- window.map = {
- getCenter: () => ({ lat: 51.505, lng: -0.09 }),
- getZoom: () => 13,
- };
-
- // Mock document.baseURI
- Object.defineProperty(document, 'baseURI', {
- value: 'https://intel.ingress.com/intel',
- });
- });
-
- it('should create a basic permalink with map view only', () => {
- const permalink = IITC.utils.makePermalink();
- expect(permalink).to.equal('/?ll=51.505,-0.09&z=13');
- });
-
- it('should create permalink with specific coordinates', () => {
- const latlng = [52.52, 13.405];
- const permalink = IITC.utils.makePermalink(latlng);
- expect(permalink).to.equal('/?pll=52.52,13.405');
- });
-
- it('should create permalink with L.LatLng object', () => {
- const latlng = { lat: 52.52, lng: 13.405 };
- const permalink = IITC.utils.makePermalink(latlng);
- expect(permalink).to.equal('/?pll=52.52,13.405');
- });
-
- it('should include map view when includeMapView option is true', () => {
- const latlng = [52.52, 13.405];
- const permalink = IITC.utils.makePermalink(latlng, { includeMapView: true });
- expect(permalink).to.equal('/?ll=51.505,-0.09&z=13&pll=52.52,13.405');
- });
-
- it('should create full URL when fullURL option is true', () => {
- const latlng = [52.52, 13.405];
- const permalink = IITC.utils.makePermalink(latlng, { fullURL: true });
- expect(permalink).to.equal('https://intel.ingress.com/?pll=52.52,13.405');
- });
-
- it('should handle both fullURL and includeMapView options', () => {
- const latlng = [52.52, 13.405];
- const permalink = IITC.utils.makePermalink(latlng, {
- fullURL: true,
- includeMapView: true,
- });
- expect(permalink).to.equal('https://intel.ingress.com/?ll=51.505,-0.09&z=13&pll=52.52,13.405');
- });
-
- it('should handle no coordinates but includeMapView option', () => {
- const permalink = IITC.utils.makePermalink(null, { includeMapView: true });
- expect(permalink).to.equal('/?ll=51.505,-0.09&z=13');
- });
-});