mirror of
				https://github.com/brianshea2/meshmap.net.git
				synced 2025-03-05 21:00:01 -08:00 
			
		
		
		
	handle special characters (e.g., newlines) in node data (#31)
This commit is contained in:
		
							parent
							
								
									92dcb58981
								
							
						
					
					
						commit
						ca2b7b3dd1
					
				|  | @ -97,7 +97,9 @@ | |||
|   } | ||||
| </style> | ||||
| <div id="header"> | ||||
|   <div><a href="https://meshmap.net/" title="A nearly live map of Meshtastic nodes seen by the official Meshtastic MQTT server">MeshMap</a></div> | ||||
|   <div> | ||||
|     <a href="https://meshmap.net/" title="A nearly live map of Meshtastic nodes seen by the official Meshtastic MQTT server">MeshMap</a> | ||||
|   </div> | ||||
|   <div> | ||||
|     <a | ||||
|       href="#" | ||||
|  | @ -126,8 +128,10 @@ | |||
|     182, 91, 46, 23, 11, 6, 3, 1, | ||||
|     1, 0, 0, 0, 0, 0, 0, 0 | ||||
|   ] | ||||
|   // encodes html reserved characters | ||||
|   const html = str => str?.replace(/["&<>]/g, match => `&#${match.charCodeAt(0)};`) | ||||
|   // encodes html reserved characters and ascii control characters | ||||
|   const html = str => str | ||||
|     ?.replace(/[\x00-\x1F]/g, c => `\\x${c.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0')}`) | ||||
|     .replace(/["&<>]/g, c => `&#${c.charCodeAt(0)};`) | ||||
|   // makes more human-readable time duration strings | ||||
|   const duration = d => { | ||||
|     let s = '' | ||||
|  | @ -232,22 +236,23 @@ | |||
|       <div class="title">${html(longName)} (${html(shortName)})</div> | ||||
|       <div>${nodeLink(nodeNum, id)} | ${html(role)} | ${html(hwModel)}</div> | ||||
|       <table><tbody> | ||||
|       ${fwVersion ? `<tr><th>Firmware</th><td>${html(fwVersion)}</td></tr>` : ''} | ||||
|       ${region ? `<tr><th>Region</th><td>${html(region)}</td></tr>` : ''} | ||||
|       ${modemPreset ? `<tr><th>Modem preset</th><td>${html(modemPreset)}</td></tr>` : ''} | ||||
|       ${hasDefaultCh ? `<tr><th>Has default channel</th><td>True</td></tr>` : ''} | ||||
|       ${onlineLocalNodes ? `<tr><th>Online local nodes</th><td>${onlineLocalNodes}</td></tr>` : ''} | ||||
|       ${batteryLevel ? `<tr><th>Power</th><td>${batteryLevel > 100 ? 'Plugged in' : `${batteryLevel}%`}${voltage ? ` (${voltage.toFixed(2)}V)` : ''}</td></tr>` : ''} | ||||
|       ${chUtil ? `<tr><th>ChUtil</th><td>${chUtil.toFixed(2)}%</td></tr>` : ''} | ||||
|       ${airUtilTx ? `<tr><th>AirUtilTX</th><td>${airUtilTx.toFixed(2)}%</td></tr>` : ''} | ||||
|       ${uptime ? `<tr><th>Uptime</th><td>${duration(uptime)}</td></tr>` : ''} | ||||
|       ${temperature ? `<tr><th>Temperature</th><td>${temperature.toFixed(1)}℃ / ${(temperature * 1.8 + 32).toFixed(1)}℉</td></tr>` : ''} | ||||
|       ${relativeHumidity ? `<tr><th>Relative Humidity</th><td>${Math.round(relativeHumidity)}%</td></tr>` : ''} | ||||
|       ${fwVersion          ? `<tr><th>Firmware</th><td>${html(fwVersion)}</td></tr>`                               : ''} | ||||
|       ${region             ? `<tr><th>Region</th><td>${html(region)}</td></tr>`                                    : ''} | ||||
|       ${modemPreset        ? `<tr><th>Modem preset</th><td>${html(modemPreset)}</td></tr>`                         : ''} | ||||
|       ${hasDefaultCh       ? `<tr><th>Has default channel</th><td>True</td></tr>`                                  : ''} | ||||
|       ${onlineLocalNodes   ? `<tr><th>Online local nodes</th><td>${onlineLocalNodes}</td></tr>`                    : ''} | ||||
|       ${batteryLevel       ? `<tr><th>Power</th><td>${batteryLevel > 100 ? 'Plugged in' : `${batteryLevel}%`}` + | ||||
|                              `${voltage ? ` (${voltage.toFixed(2)}V)` : ''}</td></tr>`                             : ''} | ||||
|       ${chUtil             ? `<tr><th>ChUtil</th><td>${chUtil.toFixed(2)}%</td></tr>`                              : ''} | ||||
|       ${airUtilTx          ? `<tr><th>AirUtilTX</th><td>${airUtilTx.toFixed(2)}%</td></tr>`                        : ''} | ||||
|       ${uptime             ? `<tr><th>Uptime</th><td>${duration(uptime)}</td></tr>`                                : ''} | ||||
|       ${temperature        ? `<tr><th>Temperature</th><td>${temperature.toFixed(1)}℃ / ` + | ||||
|                              `${(temperature * 1.8 + 32).toFixed(1)}℉</td></tr>`                             : ''} | ||||
|       ${relativeHumidity   ? `<tr><th>Relative Humidity</th><td>${Math.round(relativeHumidity)}%</td></tr>`        : ''} | ||||
|       ${barometricPressure ? `<tr><th>Barometric Pressure</th><td>${Math.round(barometricPressure)} hPa</td></tr>` : ''} | ||||
|       ${altitude ? `<tr><th>Altitude</th><td>${altitude.toLocaleString()} m above MSL</td></tr>` : ''} | ||||
|       ${precision && precisionMargins[precision-1] ? | ||||
|         `<tr><th>Location precision</th><td>± ${precisionMargins[precision-1].toLocaleString()} m (orange circle)</td></tr>` : '' | ||||
|       } | ||||
|       ${altitude           ? `<tr><th>Altitude</th><td>${altitude.toLocaleString()} m above MSL</td></tr>`         : ''} | ||||
|       ${precision && precisionMargins[precision-1] ? "<tr><th>Location precision</th><td>±" + | ||||
|                              `${precisionMargins[precision-1].toLocaleString()} m (orange circle)</td></tr>`       : ''} | ||||
|       </tbody></table> | ||||
|       <table><thead> | ||||
|       <tr><th>Last seen</th><th>via</th><th>root topic</th><th>channel</th></tr> | ||||
|  | @ -255,7 +260,9 @@ | |||
|       ${Array.from( | ||||
|         new Map( | ||||
|           Object.entries(seenBy) | ||||
|             .map(([topic, seen]) => (m => ({seen, via: m[3] ?? id, root: m[1], chan: m[2]}))(topic.match(/^(.*)(?:\/2\/e\/(.*)\/(![0-9a-f]+)|\/2\/map\/)$/))) | ||||
|             .map(([topic, seen]) => (m => ({seen, via: m[3] ?? id, root: m[1], chan: m[2]}))( | ||||
|               topic.match(/^(.*)(?:\/2\/e\/(.*)\/(![0-9a-f]+)|\/2\/map\/)$/s) | ||||
|             )) | ||||
|             .sort((a, b) => a.seen - b.seen) | ||||
|             .map(v => [v.via, v]) | ||||
|         ).values(), | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue