diff --git a/core/code/map_data_render.js b/core/code/map_data_render.js index 330164535..fc1c423d9 100644 --- a/core/code/map_data_render.js +++ b/core/code/map_data_render.js @@ -330,7 +330,7 @@ window.Render.prototype.createPlaceholderPortalEntity = function (guid, latE6, l ]; this.createPortalEntity(ent, 'core'); // placeholder -} +}; /** * Creates a portal entity from the provided game entity data. @@ -351,8 +351,9 @@ window.Render.prototype.createPortalEntity = function (ent, details) { // add missing fields data.guid = guid; - if (!data.timestamp) + if (!data.timestamp) { data.timestamp = ent[1]; + } // LEGACY - TO BE REMOVED AT SOME POINT! use .guid, .timestamp and .data instead data.ent = ent; @@ -386,14 +387,14 @@ window.Render.prototype.createPortalEntity = function (ent, details) { // check for URL links to portal, and select it if this is the one if (window.urlPortalLL && window.urlPortalLL[0] === latlng.lat && window.urlPortalLL[1] === latlng.lng) { // URL-passed portal found via pll parameter - set the guid-based parameter - log.log('urlPortalLL ' + window.urlPortalLL[0] + ',' + urlPortalLL[1] + ' matches portal GUID ' + data.guid); + log.log('urlPortalLL ' + window.urlPortalLL[0] + ',' + window.urlPortalLL[1] + ' matches portal GUID ' + data.guid); window.urlPortal = data.guid; window.urlPortalLL = undefined; // clear the URL parameter so it's not matched again } if (window.urlPortal === data.guid) { // URL-passed portal found via guid parameter - set it as the selected portal - log.log('urlPortal GUID ' + urlPortal + ' found - selecting...'); + log.log('urlPortal GUID ' + window.urlPortal + ' found - selecting...'); window.selectedPortal = data.guid; window.urlPortal = undefined; // clear the URL parameter so it's not matched again } @@ -405,26 +406,28 @@ window.Render.prototype.createPortalEntity = function (ent, details) { marker.updateDetails(data); - window.runHooks('portalAdded', {portal: marker, previousData: previousData}); + window.runHooks('portalAdded', { portal: marker, previousData: previousData }); } else { - marker = createMarker(latlng, data); + marker = window.createMarker(latlng, data); // in case of incomplete data while having fresh details in cache, update the portal with those details - if (portalDetail.isFresh(guid)) { - var oldDetails = portalDetail.get(guid); + if (window.portalDetail.isFresh(guid)) { + var oldDetails = window.portalDetail.get(guid); if (data.timestamp > oldDetails.timestamp) { // data is more recent than the cached details so we remove them from the cache - portalDetail.remove(guid); - } else if (marker.willUpdate(oldDetails)) + window.portalDetail.remove(guid); + } else if (marker.willUpdate(oldDetails)) { marker.updateDetails(oldDetails); + } } window.runHooks('portalAdded', { portal: marker }); window.portals[data.guid] = marker; - if (selectedPortal === data.guid) + if (window.selectedPortal === data.guid) { marker.renderDetails(); + } } window.ornaments.addPortal(marker); diff --git a/core/code/portal_detail_display.js b/core/code/portal_detail_display.js index ff1735709..9c2489b7e 100644 --- a/core/code/portal_detail_display.js +++ b/core/code/portal_detail_display.js @@ -69,10 +69,12 @@ window.renderPortalUrl = function (lat, lng, title, guid) { * * @function renderPortalDetails * @param {string|null} guid - The globally unique identifier of the portal to display details for. + * @param {boolean} [forceSelect=false] - If true, forces the portal to be selected even if it's already the current portal. */ -window.renderPortalDetails = function(guid, forceSelect) { - if (forceSelect || window.selectedPortal !== guid) +window.renderPortalDetails = function (guid, forceSelect) { + if (forceSelect || window.selectedPortal !== guid) { window.selectPortal(window.portals[guid] ? guid : null, 'renderPortalDetails'); + } if ($('#sidebar').is(':visible')) { window.resetScrollOnNewPortal(); window.renderPortalDetails.lastVisible = guid; @@ -184,7 +186,7 @@ window.renderPortalDetails = function(guid, forceSelect) { window.renderPortalUrl(lat, lng, title, guid); // compatibility - var data = hasFullDetails ? getPortalSummaryData(details) : details; + var data = hasFullDetails ? window.getPortalSummaryData(details) : details; // only run the hooks when we have a portalDetails object - most plugins rely on the extended data // TODO? another hook to call always, for any plugins that can work with less data? @@ -348,11 +350,15 @@ window.selectPortal = function (guid, event) { if (!update && oldPortal) oldPortal.setSelected(false); // Change style of selected portal - if(newPortal) newPortal.setSelected(true); + if (newPortal) newPortal.setSelected(true); window.setPortalIndicators(newPortal); - window.runHooks('portalSelected', { selectedPortalGuid: guid, unselectedPortalGuid: oldPortalGuid, event: event }); + window.runHooks('portalSelected', { + selectedPortalGuid: guid, + unselectedPortalGuid: oldPortalGuid, + event: event, + }); return update; }; diff --git a/core/code/portal_info.js b/core/code/portal_info.js index 436ee0665..9a210901f 100644 --- a/core/code/portal_info.js +++ b/core/code/portal_info.js @@ -59,12 +59,20 @@ window.getCurrentPortalEnergy = function (d) { return nrg; }; -window.getPortalHealth = function(d) { - var max = getTotalPortalEnergy(d); - var cur = getCurrentPortalEnergy(d); +/** + * Calculates the health percentage of a portal based on its current and total energy. + * + * @function getPortalHealth + * @param {Object} d - The portal detail object containing resonator information. + * @returns {number} The portal health as a percentage (0-100). + * Returns 0 if the portal has no total energy. + */ +window.getPortalHealth = function (d) { + var max = window.getTotalPortalEnergy(d); + var cur = window.getCurrentPortalEnergy(d); - return max>0 ? Math.floor(cur/max*100) : 0; -} + return max > 0 ? Math.floor((cur / max) * 100) : 0; +}; /** * Calculates the range of a portal for creating links. The range depends on portal level and any installed Link Amps. @@ -75,7 +83,7 @@ window.getPortalHealth = function(d) { * total range after applying the boost (`range`), * and a boolean indicating if the portal is linkable (`isLinkable`). */ -window.getPortalRange = function(d) { +window.getPortalRange = function (d) { // formula by the great gals and guys at // http://decodeingress.me/2012/11/18/ingress-portal-levels-and-link-range/ var range = { diff --git a/core/code/portal_marker.js b/core/code/portal_marker.js index 59ade0bd5..e00bf597f 100644 --- a/core/code/portal_marker.js +++ b/core/code/portal_marker.js @@ -1,31 +1,25 @@ -/* global L -- eslint */ +/* global L, log -- eslint */ /** * @file This file contains the code related to creating and updating portal markers on the map. * @module portal_marker */ -var portalBaseStyle = { - stroke: true, - opacity: 1, - fill: true, - fillOpacity: 0.5, - interactive: true, -}; - // portal hooks -function handler_portal_click (e) { +function handler_portal_click(e) { window.selectPortal(e.target.options.guid, e.type); - window.renderPortalDetails(e.target.options.guid) + window.renderPortalDetails(e.target.options.guid); } -function handler_portal_dblclick (e) { + +function handler_portal_dblclick(e) { window.selectPortal(e.target.options.guid, e.type); - window.renderPortalDetails(e.target.options.guid) - window.map.setView(e.target.getLatLng(), DEFAULT_ZOOM); + window.renderPortalDetails(e.target.options.guid); + window.map.setView(e.target.getLatLng(), window.DEFAULT_ZOOM); } -function handler_portal_contextmenu (e) { + +function handler_portal_contextmenu(e) { window.selectPortal(e.target.options.guid, e.type); - window.renderPortalDetails(e.target.options.guid) + window.renderPortalDetails(e.target.options.guid); if (window.isSmartphone()) { window.show('info'); } else if (!$('#scrollwrapper').is(':visible')) { @@ -55,59 +49,65 @@ L.PortalMarker = L.CircleMarker.extend({ LEVEL_TO_RADIUS: [7, 7, 7, 7, 8, 8, 9, 10, 11], }, - initialize: function(latlng, data) { + initialize: function (latlng, data) { L.CircleMarker.prototype.initialize.call(this, latlng); - this._selected = data.guid === selectedPortal; + this._selected = data.guid === window.selectedPortal; this.updateDetails(data); this.on('click', handler_portal_click); this.on('dblclick', handler_portal_dblclick); this.on('contextmenu', handler_portal_contextmenu); }, + willUpdate: function (details) { // details are from a placeholder if (details.level === undefined) { // if team differs and corresponding link is more recent (ignore field) - if (this._details.timestamp < details.timestamp && this._details.team !== details.team) - return true; - // in any other case - return false; + return this._details.timestamp < details.timestamp && this._details.team !== details.team; } // more recent timestamp, this occurs when the data has changed because of: // - resonator deploy/upgrade // - mod deploy // - recharge/damage/decay // - portal edit (title, location, portal main picture) - if (this._details.timestamp < details.timestamp) + if (this._details.timestamp < details.timestamp) { return true; + } // current marker is a placeholder, and details is real data - if (this.isPlaceholder() && this._details.team === details.team) + if (this.isPlaceholder() && this._details.team === details.team) { return true; + } // even if we get history that was missing ? is it even possible ? - if (this._details.timestamp > details.timestamp) + if (this._details.timestamp > details.timestamp) { return false; + } // this._details.timestamp === details.timestamp // get new history if (details.history) { - if (!this._details.history) + if (!this._details.history) { return true; - if (this._details.history._raw !== details.history._raw) + } + if (this._details.history._raw !== details.history._raw) { return true; + } } // get details portal data - if (!this._details.mods && details.mods) + if (!this._details.mods && details.mods) { return true; + } return false; }, - updateDetails: function(details) { + + updateDetails: function (details) { if (this._details) { // portal has been moved - if (this._details.latE6 !== details.latE6 || this._details.lngE6 !== details.lngE6) - this.setLatLng(L.latLng(details.latE6/1E6, details.lngE6/1E6)); + if (this._details.latE6 !== details.latE6 || this._details.lngE6 !== details.lngE6) { + this.setLatLng(L.latLng(details.latE6 / 1e6, details.lngE6 / 1e6)); + } // core data from a placeholder if (details.level === undefined) { @@ -119,18 +119,34 @@ L.PortalMarker = L.CircleMarker.extend({ details.history = this._details.history; this._details = details; } - } else if (this._details.timestamp == details.timestamp) { + } else if (this._details.timestamp === details.timestamp) { // we got more details (core/summary -> summary/detailed/extended) var localThis = this; - ["level", "health", "resCount", "image", "title", "ornaments", "mission", "mission50plus", "artifactBrief", "mods", "resonators", "owner", "artifactDetail"].forEach(function (prop) { + [ + 'level', + 'health', + 'resCount', + 'image', + 'title', + 'ornaments', + 'mission', + 'mission50plus', + 'artifactBrief', + 'mods', + 'resonators', + 'owner', + 'artifactDetail', + ].forEach(function (prop) { if (details[prop]) localThis._details[prop] = details[prop]; }); // smarter update for history (cause it's missing sometimes) if (details.history) { - if (!this._details.history) this._details.history = details.history; - else { - if (this._details.history._raw & details.history._raw != this._details.history._raw) - log.warn("new portal data has lost some history"); + if (!this._details.history) { + this._details.history = details.history; + } else { + if (this._details.history._raw && details.history._raw !== this._details.history._raw) { + log.warn('new portal data has lost some history'); + } this._details.history._raw |= details.history._raw; ['visited', 'captured', 'scoutControlled'].forEach(function (prop) { localThis._details.history[prop] ||= details.history[prop]; @@ -141,17 +157,23 @@ L.PortalMarker = L.CircleMarker.extend({ this._details.ent = details.ent; } else { // permanent data (history only) - if (!details.history) details.history = this._details.history; + if (!details.history) { + details.history = this._details.history; + } this._details = details; } - } else this._details = details; + } else { + this._details = details; + } this._level = parseInt(this._details.level) || 0; this._team = window.teamStringToId(this._details.team); // the data returns unclaimed portals as level 1 - but IITC wants them treated as level 0 - if (this._team === TEAM_NONE) this._level = 0; + if (this._team === window.TEAM_NONE) { + this._level = 0; + } // compatibility var dataOptions = { @@ -160,7 +182,7 @@ L.PortalMarker = L.CircleMarker.extend({ team: this._team, ent: this._details.ent, // LEGACY - TO BE REMOVED AT SOME POINT! use .guid, .timestamp and .data instead timestamp: this._details.timestamp, - data: this._details + data: this._details, }; L.setOptions(this, dataOptions); @@ -170,60 +192,71 @@ L.PortalMarker = L.CircleMarker.extend({ this.setSelected(); }, + renderDetails() { if (!this._rendering) { this._rendering = true; - renderPortalDetails(this._details.guid); + window.renderPortalDetails(this._details.guid); this._rendering = false; } }, + getDetails: function () { return this._details; }, + isPlaceholder: function () { return this._details.level === undefined; }, + hasFullDetails: function () { - return !!this._details.mods + return !!this._details.mods; }, - setStyle: function (style) { // stub for highlighters + + setStyle: function (style) { + // stub for highlighters L.Util.setOptions(this, style); return this; }, + setMarkerStyle: function (style) { var styleOptions = L.Util.extend(this._style(), style); L.Util.setOptions(this, styleOptions); - L.Util.setOptions(this, highlightPortal(this)); + L.Util.setOptions(this, window.highlightPortal(this)); - var selected = L.extend( - { radius: this.options.radius }, - this._selected && { color: COLOR_SELECTED_PORTAL } - ); + var selected = L.extend({ radius: this.options.radius }, this._selected && { color: window.COLOR_SELECTED_PORTAL }); return L.CircleMarker.prototype.setStyle.call(this, selected); }, + setSelected: function (selected) { - if (selected === false) + if (selected === false) { this._selected = false; - else + } else { this._selected = this._selected || selected; + } this.setMarkerStyle(); - if (this._selected && window.map.hasLayer(this)) + if (this._selected && window.map.hasLayer(this)) { this.bringToFront(); + } }, + _style: function () { var dashArray = null; // dashed outline for placeholder portals - if (this.isPlaceholder()) dashArray = L.PortalMarker.placeholderStyle.dashArray; + if (this.isPlaceholder()) { + dashArray = L.PortalMarker.placeholderStyle.dashArray; + } return L.extend(this._scale(), L.PortalMarker.portalBaseStyle, { - color: COLORS[this._team], - fillColor: COLORS[this._team], - dashArray: dashArray + color: window.COLORS[this._team], + fillColor: window.COLORS[this._team], + dashArray: dashArray, }); }, + _scale: function () { var scale = window.portalMarkerScale(); @@ -262,22 +295,22 @@ window.portalMarkerScale = function () { * @function createMarker * @param {L.LatLng} latlng - The latitude and longitude where the marker will be placed. * @param {Object} data - The IITC-specific entity data to be stored in the marker options. - * @returns {L.circleMarker} A Leaflet circle marker representing the portal. + * @returns {L.PortalMarker} A Leaflet circle marker representing the portal. */ -window.createMarker = function(latlng, data) { +window.createMarker = function (latlng, data) { return new L.PortalMarker(latlng, data); -} +}; /** * Sets the style of a portal marker, including options for when the portal is selected. * * @function setMarkerStyle - * @param {L.circleMarker} marker - The portal marker whose style will be set. + * @param {L.PortalMarker} marker - The portal marker whose style will be set. * @param {boolean} selected - Indicates if the portal is selected. */ -window.setMarkerStyle = function(marker, selected) { +window.setMarkerStyle = function (marker, selected) { marker.setSelected(selected); -} +}; /** * Determines the style options for a portal marker based on its details.