forked from MapComplete/MapComplete
		
	Fix loading of relative images in custom themes
This commit is contained in:
		
							parent
							
								
									8d79d94e7b
								
							
						
					
					
						commit
						a3b32a3697
					
				
					 7 changed files with 346 additions and 235 deletions
				
			
		|  | @ -2,7 +2,8 @@ import {LayoutConfigJson} from "../Json/LayoutConfigJson"; | |||
| import {Utils} from "../../../Utils"; | ||||
| import LineRenderingConfigJson from "../Json/LineRenderingConfigJson"; | ||||
| import {LayerConfigJson} from "../Json/LayerConfigJson"; | ||||
| import {DesugaringContext, DesugaringStep, Fuse, OnEvery} from "./Conversion"; | ||||
| import {DesugaringStep, Fuse, OnEvery} from "./Conversion"; | ||||
| import * as metapaths from "../../../assets/layoutconfigmeta.json" | ||||
| 
 | ||||
| export class UpdateLegacyLayer extends DesugaringStep<LayerConfigJson | string | { builtin, override }> { | ||||
| 
 | ||||
|  | @ -157,3 +158,103 @@ export class FixLegacyTheme extends Fuse<LayoutConfigJson> { | |||
|         ); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| export class FixImages extends DesugaringStep<LayoutConfigJson> { | ||||
|     private readonly _knownImages: Set<string>; | ||||
| 
 | ||||
|     constructor(knownImages: Set<string>) { | ||||
|         super("Walks over the entire theme and replaces images to the relative URL. Only works if the ID of the theme is an URL"); | ||||
|         this._knownImages = knownImages; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Walks the path into the object till the end. | ||||
|      * | ||||
|      * If a list is encountered, this is tranparently walked recursively on every object. | ||||
|      * | ||||
|      * The leaf objects are replaced | ||||
|      */ | ||||
|     private static WalkPath(path: string[], object: any, replaceLeaf: ((leaf: any) => any)) { | ||||
|         const head = path[0] | ||||
|         if (path.length === 1) { | ||||
|             // We have reached the leaf
 | ||||
|             const leaf = object[head]; | ||||
|             if (leaf !== undefined) { | ||||
|                 object[head] = replaceLeaf(leaf) | ||||
|             } | ||||
|             return | ||||
| 
 | ||||
|         } | ||||
|         const sub = object[head] | ||||
|         if (sub === undefined) { | ||||
|             return; | ||||
|         } | ||||
|         if (typeof sub !== "object") { | ||||
|             return; | ||||
|         } | ||||
|         if (sub["forEach"] !== undefined) { | ||||
|             sub.forEach(el => FixImages.WalkPath(path.slice(1), el, replaceLeaf)) | ||||
|             return; | ||||
|         } | ||||
|         FixImages.WalkPath(path.slice(1), sub, replaceLeaf) | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors?: string[]; warnings?: string[] } { | ||||
|         let url: URL; | ||||
|         console.log("Fixing images!") | ||||
|         try { | ||||
|             url = new URL(json.id) | ||||
|         } catch (e) { | ||||
|             // Not a URL, we don't rewrite
 | ||||
|             return {result: json} | ||||
|         } | ||||
| 
 | ||||
|         const absolute =  url.protocol +"//"+url.host | ||||
|         let relative = url.protocol +"//"+ url.host + url.pathname  | ||||
|         relative = relative.substring(0, relative.lastIndexOf("/")) | ||||
|         const self = this; | ||||
| 
 | ||||
|         function replaceString(leaf: string) { | ||||
|             if (self._knownImages.has(leaf)) { | ||||
|                 return leaf; | ||||
|             } | ||||
|             if (leaf.startsWith("./")) { | ||||
|                 return relative + leaf.substring(1) | ||||
|             } | ||||
|             if (leaf.startsWith("/")) { | ||||
|                 return absolute + leaf | ||||
|             } | ||||
|             return leaf; | ||||
|         } | ||||
| 
 | ||||
|         json = Utils.Clone(json) | ||||
| 
 | ||||
|         let paths = metapaths["default"] ?? metapaths | ||||
| 
 | ||||
|         for (const metapath of paths) { | ||||
|             if (metapath.typeHint !== "image" && metapath.typeHint !== "icon") { | ||||
|                 continue | ||||
|             } | ||||
|             FixImages.WalkPath(metapath.path, json, leaf => { | ||||
|                 console.log("Detected leaf: ", leaf) | ||||
|                 if (typeof leaf === "string") { | ||||
|                     return replaceString(leaf) | ||||
|                 } | ||||
| 
 | ||||
|                 if (metapath.type["some"] !== undefined && (<any[]>metapath.type).some(t => t["$ref"] == "\"#/definitions/TagRenderingConfigJson\"")) { | ||||
|                     console.log("Possibly found a tagrendering") | ||||
|                      | ||||
|                 } | ||||
| 
 | ||||
|                 return leaf; | ||||
|             }) | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         return { | ||||
|             result: json | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | @ -37,7 +37,8 @@ export default interface PointRenderingConfigJson { | |||
|      * | ||||
|      * Note: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle | ||||
|      */ | ||||
|     iconBadges?: { if: string | AndOrTagConfigJson,  | ||||
|     iconBadges?: {  | ||||
|         if: string | AndOrTagConfigJson,  | ||||
|         /** | ||||
|          * Badge to show | ||||
|          * Type: icon | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue