Allow data URI scheme for custom images (#1196)

* Allow data URL external images

* fix

* removed inconsistency
This commit is contained in:
Ruichka 2025-03-08 16:51:48 +03:00 committed by GitHub
parent f859439fc8
commit 8131f25456
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 32 additions and 32 deletions

View file

@ -8116,8 +8116,8 @@
<script src="main.js?v=1.108.1"></script>
<script defer src="modules/ui/style.js?v=1.108.4"></script>
<script defer src="modules/ui/editors.js?v=1.108.1"></script>
<script defer src="modules/ui/tools.js?v=1.108.4"></script>
<script defer src="modules/ui/editors.js?v=1.108.5"></script>
<script defer src="modules/ui/tools.js?v=1.108.5"></script>
<script defer src="modules/ui/world-configurator.js?v=1.105.4"></script>
<script defer src="modules/ui/heightmap-editor.js?v=1.105.2"></script>
<script defer src="modules/ui/provinces-editor.js?v=1.108.1"></script>
@ -8144,13 +8144,13 @@
<script defer src="modules/ui/burgs-overview.js?v=1.105.15"></script>
<script defer src="modules/ui/routes-overview.js?v=1.104.3"></script>
<script defer src="modules/ui/rivers-overview.js?v=1.99.00"></script>
<script defer src="modules/ui/military-overview.js?v=1.107.0"></script>
<script defer src="modules/ui/regiments-overview.js?v=1.107.0"></script>
<script defer src="modules/ui/markers-overview.js?v=1.107.0"></script>
<script defer src="modules/ui/regiment-editor.js?v=1.108.1"></script>
<script defer src="modules/ui/battle-screen.js?v=1.107.2"></script>
<script defer src="modules/ui/military-overview.js?v=1.108.5"></script>
<script defer src="modules/ui/regiments-overview.js?v=1.108.5"></script>
<script defer src="modules/ui/markers-overview.js?v=1.108.5"></script>
<script defer src="modules/ui/regiment-editor.js?v=1.108.5"></script>
<script defer src="modules/ui/battle-screen.js?v=1.108.5"></script>
<script defer src="modules/ui/emblems-editor.js?v=1.99.00"></script>
<script defer src="modules/ui/markers-editor.js?v=1.107.0"></script>
<script defer src="modules/ui/markers-editor.js?v=1.108.5"></script>
<script defer src="modules/ui/3d.js?v=1.99.00"></script>
<script defer src="modules/ui/submap-tool.js?v=1.106.2"></script>
<script defer src="modules/ui/transform-tool.js?v=1.106.2"></script>
@ -8166,11 +8166,11 @@
<script defer src="modules/renderers/draw-features.js?v=1.108.2"></script>
<script defer src="modules/renderers/draw-borders.js?v=1.104.0"></script>
<script defer src="modules/renderers/draw-heightmap.js?v=1.104.0"></script>
<script defer src="modules/renderers/draw-markers.js?v=1.107.0"></script>
<script defer src="modules/renderers/draw-markers.js?v=1.108.5"></script>
<script defer src="modules/renderers/draw-scalebar.js?v=1.108.1"></script>
<script defer src="modules/renderers/draw-temperature.js?v=1.104.0"></script>
<script defer src="modules/renderers/draw-emblems.js?v=1.104.0"></script>
<script defer src="modules/renderers/draw-military.js?v=1.108.1"></script>
<script defer src="modules/renderers/draw-military.js?v=1.108.5"></script>
<script defer src="modules/renderers/draw-state-labels.js?v=1.108.1"></script>
<script defer src="modules/renderers/draw-burg-labels.js?v=1.108.1"></script>
<script defer src="modules/renderers/draw-burg-icons.js?v=1.104.0"></script>

View file

@ -42,7 +42,7 @@ function drawMarker(marker, rescale = 1) {
const viewX = rn(x - zoomSize / 2, 1);
const viewY = rn(y - zoomSize, 1);
const isExternal = icon.startsWith("http");
const isExternal = icon.startsWith("http") || icon.startsWith("data:image");
return /* html */ `
<svg id="${id}" viewbox="0 0 30 30" width="${zoomSize}" height="${zoomSize}" x="${viewX}" y="${viewY}">

View file

@ -56,14 +56,14 @@ const drawRegiments = function (regiments, s) {
.attr("text-rendering", "optimizeSpeed")
.attr("x", d => x(d) - size)
.attr("y", d => d.y)
.text(d => (d.icon.startsWith("http") ? "" : d.icon));
.text(d => (d.icon.startsWith("http") || d.icon.startsWith("data:image") ? "" : d.icon));
g.append("image")
.attr("class", "regimentImage")
.attr("x", d => x(d) - h)
.attr("y", d => y(d))
.attr("height", h)
.attr("width", h)
.attr("href", d => (d.icon.startsWith("http") ? d.icon : ""));
.attr("href", d => (d.icon.startsWith("http") || d.icon.startsWith("data:image") ? d.icon : ""));
};
const drawRegiment = function (reg, stateId) {
@ -109,14 +109,14 @@ const drawRegiment = function (reg, stateId) {
.attr("text-rendering", "optimizeSpeed")
.attr("x", x1 - size)
.attr("y", reg.y)
.text(reg.icon.startsWith("http") ? "" : reg.icon);
.text(reg.icon.startsWith("http") || reg.icon.startsWith("data:image") ? "" : reg.icon);
g.append("image")
.attr("class", "regimentImage")
.attr("x", x1 - h)
.attr("y", y1)
.attr("height", h)
.attr("width", h)
.attr("href", reg.icon.startsWith("http") ? reg.icon : "");
.attr("href", reg.icon.startsWith("http") || reg.icon.startsWith("data:image") ? reg.icon : "");
};
// move one regiment to another

View file

@ -131,7 +131,7 @@ class Battle {
for (const u of options.military) {
const label = capitalize(u.name.replace(/_/g, " "));
const isExternal = u.icon.startsWith("http");
const isExternal = u.icon.startsWith("http") || u.icon.startsWith("data:image");
const iconHTML = isExternal ? `<img src="${u.icon}" width="15" height="15">` : u.icon;
headers += `<th data-tip="${label}">${iconHTML}</th>`;
}
@ -148,7 +148,7 @@ class Battle {
const distance = (Math.hypot(this.y - regiment.by, this.x - regiment.bx) * distanceScale) | 0; // distance between regiment and its base
const color = state.color[0] === "#" ? state.color : "#999";
const isExternal = regiment.icon.startsWith("http");
const isExternal = regiment.icon.startsWith("http") || regiment.icon.startsWith("data:image");
const iconHtml = isExternal
? `<image href="${regiment.icon}" x="0.1em" y="0.1em" width="1.2em" height="1.2em"></image>`
: `<text x="50%" y="1em" style="text-anchor: middle">${regiment.icon}</text>`;

View file

@ -1171,7 +1171,7 @@ function selectIcon(initial, callback) {
// find external images used as icons and show them
const externalResources = new Set();
const isExternal = url => url.startsWith("http");
const isExternal = url => url.startsWith("http") || url.startsWith("data:image");
options.military.forEach(unit => {
if (isExternal(unit.icon)) externalResources.add(unit.icon);
@ -1204,14 +1204,14 @@ function selectIcon(initial, callback) {
const image = document.createElement("div");
image.style.cssText = `width: 2.2em; height: 2.2em; background-size: cover; background-image: url(${url})`;
addedIcons.appendChild(image);
image.onclick = () => callback(ulr);
image.onclick = () => callback(url);
}
byId("addImage").onclick = function () {
const input = this.previousElementSibling;
const ulr = input.value;
if (!ulr) return tip("Enter image URL to add", false, "error", 4000);
if (!ulr.match(/^(http|https):\/\//)) return tip("Enter valid URL", false, "error", 4000);
if (!ulr.match(/^((http|https):\/\/)|data\:image\//)) return tip("Enter valid URL", false, "error", 4000);
addExternalImage(ulr);
callback(ulr);
input.value = "";

View file

@ -95,7 +95,7 @@ function editMarker(markerI) {
}
function updateInputs() {
byId("markerIcon").innerHTML = marker.icon.startsWith("http")
byId("markerIcon").innerHTML = marker.icon.startsWith("http") || marker.icon.startsWith("data:image")
? `<img src="${marker.icon}" style="width: 1em; height: 1em;">`
: marker.icon;
@ -117,7 +117,7 @@ function editMarker(markerI) {
function changeMarkerIcon() {
selectIcon(marker.icon, value => {
const isExternal = value.startsWith("http");
const isExternal = value.startsWith("http") || value.startsWith("data:image");
byId("markerIcon").innerHTML = isExternal ? `<img src="${value}" style="width: 1em; height: 1em;">` : value;
getSameTypeMarkers().forEach(marker => {
@ -194,7 +194,7 @@ function editMarker(markerI) {
}
function redrawIcon({i, hidden, icon, dx = 50, dy = 50, px = 12}) {
const isExternal = icon.startsWith("http");
const isExternal = icon.startsWith("http") || icon.startsWith("data:image");
const iconText = !hidden && document.querySelector(`#marker${i} > text`);
if (iconText) {

View file

@ -72,7 +72,7 @@ function overviewMarkers() {
return /* html */ `
<div class="states" data-i=${i} data-type="${type}">
${
icon.startsWith("http")
icon.startsWith("http") || icon.startsWith("data:image")
? `<img src="${icon}" data-tip="Marker icon" style="width:1.2em; height:1.2em; vertical-align: middle;">`
: `<span data-tip="Marker icon" style="width:1.2em">${icon}</span>`
}

View file

@ -286,7 +286,7 @@ function overviewMilitary() {
if (type === "icon") {
return selectIcon(el.textContent, function (value) {
el.innerHTML = value.startsWith("http")
el.innerHTML = value.startsWith("http") || value.startsWith("data:image")
? `<img src="${value}" style="width:1.2em;height:1.2em;pointer-events:none;">`
: value;
});
@ -339,7 +339,7 @@ function overviewMilitary() {
row.innerHTML = /* html */ `<td>
<button data-type="icon" data-tip="Click to select unit icon">
${
icon.startsWith("http")
icon.startsWith("http") || icon.startsWith("data:image")
? `<img src="${icon}" style="width:1.2em;height:1.2em;pointer-events:none;">`
: icon || ""
}

View file

@ -44,7 +44,7 @@ function editRegiment(selector) {
function updateRegimentData(regiment) {
byId("regimentType").className = regiment.n ? "icon-anchor" : "icon-users";
byId("regimentName").value = regiment.name;
byId("regimentEmblem").innerHTML = regiment.icon.startsWith("http")
byId("regimentEmblem").innerHTML = regiment.icon.startsWith("http") || regiment.icon.startsWith("data:image")
? `<img src="${regiment.icon}" style="width: 1em; height: 1em;">`
: regiment.icon;
@ -158,7 +158,7 @@ function editRegiment(selector) {
selectIcon(regiment.icon, value => {
regiment.icon = value;
const isExternal = value.startsWith("http");
const isExternal = value.startsWith("http") || value.startsWith("data:image");
byId("regimentEmblem").innerHTML = isExternal ? `<img src="${value}" style="width: 1em; height: 1em;">` : value;
elSelected.querySelector(".regimentIcon").innerHTML = isExternal ? "" : value;
elSelected.querySelector(".regimentImage").setAttribute("href", isExternal ? value : "");

View file

@ -73,7 +73,7 @@ function overviewRegiments(state) {
<fill-box data-tip="${s.fullName}" fill="${s.color}" disabled></fill-box>
<input data-tip="${s.fullName}" style="width:6em" value="${s.name}" readonly />
${
r.icon.startsWith("http")
r.icon.startsWith("http") || r.icon.startsWith("data:image")
? `<img src="${r.icon}" data-tip="Regiment's emblem" style="width:1.2em; height:1.2em; vertical-align: middle;">`
: `<span data-tip="Regiment's emblem" style="width:1em">${r.icon}</span>`
}

View file

@ -872,7 +872,7 @@ function configMarkersGeneration() {
</tr></thead>`;
const lines = config.map(({type, icon, multiplier}) => {
const isExternal = icon.startsWith("http");
const isExternal = icon.startsWith("http") || icon.startsWith("data:image");
return /* html */ `<tr>
<td><input class="type" value="${type}" /></td>
@ -898,7 +898,7 @@ function configMarkersGeneration() {
const icon = image.getAttribute("src") || emoji.textContent;
selectIcon(icon, value => {
const isExternal = value.startsWith("http");
const isExternal = value.startsWith("http") || value.startsWith("data:image");
image.setAttribute("src", isExternal ? value : "");
image.hidden = !isExternal;
emoji.textContent = isExternal ? "" : value;

View file

@ -13,7 +13,7 @@
* Example: 1.102.2 -> Major version 1, Minor version 102, Patch version 2
*/
const VERSION = "1.108.4";
const VERSION = "1.108.5";
if (parseMapVersion(VERSION) !== VERSION) alert("versioning.js: Invalid format or parsing function");
{